Яка різниця міжкомандами
set
таenv
командами?Коли / слід використовувати один на відміну від іншого?
Як вони взагалі викликаються? (Типове використання; сценарій випадку).
Яка різниця міжкомандамиset
таenv
командами?
Коли / слід використовувати один на відміну від іншого?
Як вони взагалі викликаються? (Типове використання; сценарій випадку).
Відповіді:
set
це команда вбудованої оболонки .
(Оскільки це питання позначено оболонками Unix, я опускаю команду MS Windows.)
set
Вбудована команда визначена в стандарті POSIX з рядом особливостей.
Основне призначення set
вбудованого - це
встановити або скасувати параметри та позиційні параметри.
Позиційні параметри передаються оболонці (зазвичай це сценарій - але може бути інтерактивним) як аргументи викликаючої програми - зазвичай (але не обов'язково) інший оболонку. Перший параметр доступний як $1
, другий як $2
і т.д.
set
Команда може управляти цими параметрами. Кожен поданий йому аргумент встановлюється як позиційний параметр, наприклад
$ set one two
$ echo "$1"
one
$ echo "$2"
two
set --
знімає всі позиційні параметри:
$ set --
$ echo $1 # no output
Однак специфікація POSIX також описує інші види використання для set
:
Запуск set
сам по собі друкує імена та значення всіх змінних оболонок. Це включає
Приклад:
$ set
HOME='/home/ant'
IFS='
'
LANG='en_US.UTF-8'
LANGUAGE='en_US:en'
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
PS1='# '
PS2='> '
PS4='+ '
PWD='/home/ant'
У наведеному вище списку, HOME
, LANG
і PATH
є змінними середовищами в той час як IFS
і PS1
для PS4
всіх змінних оболонок , які були встановлені в поточній оболонці.
Примітка. В оболонці Bash set
вбудований також друкує визначення функцій оболонки. Для отримання додаткової інформації див. Посібник Bash для набору.
set
також використовується для управління атрибутами оболонки, зазвичай (але не обов'язково) інтерактивну оболонку. Це робиться, запустивши його з певними заздалегідь визначеними параметрами (щоб відрізнити їх від аргументів, які використовуються для встановлення позиційних параметрів, як описано вище).
Коли параметри вказані, вони повинні встановлювати або скасовувати атрибути оболонки
Ці параметри детально описані в специфікації POSIX . Одним із прикладів є
set -f
-f
Параметр відключає розширення імені шляху (підстановку) від здійснюються з допомогою поточної оболонки. Ця поведінка також може бути налаштована за допомогою еквівалентної команди:
set -o noglob
Оболонки, такі як Bash, розширюються в цьому списку, включаючи такі параметри, як -B
(або -o braceexpand
); це вмикає розширення дужок (функції лише для Bash) у поточній оболонці.
На відміну від цього set
, env
команда є звичайною зовнішньою командою, тобто не є частиною оболонки. За умовами (для портативності), у кожному середовищі Unix env
програма є виконуваним файлом, встановленим в /usr/bin
каталог.
env
Інструмент також визначається POSIX .
Основна мета env
команди - запуск команди з іншим / модифікованим середовищем.
env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
Наступний приклад запускає git status
команду з набором двох змінних середовища:
env GIT_DIR=~/notes/.git/ GIT_WORK_TREE=~/notes/ git status
-i
Варіант з env
може бути використаний для виконання команди з порожньою середовищем, тобто ніякі змінні оточення не успадковуються від батьківського процесу.
Зауважте, що якщо тільки змінити одну або дві змінні середовища та використовувати оболонку Bash, немає необхідності, env
оскільки сам Bash може тимчасово змінювати середовище для однієї команди. У Bash, наведений вище приклад можна було просто запустити так:
GIT_DIR=~/notes/.git/ GIT_WORK_TREE=~/notes/ git status
Якщо команда не надається, друкується поточне середовище.
$ env
MAIL=/var/mail/root
LANGUAGE=en_US:en
USER=ant
HOME=/home/ant
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LANG=en_US.UTF-8
Зауважте, що це друкує лише змінні середовища, а не змінні оболонки, такі як PS1
або IFS
.
Ще одне використання env
- пошук команди PATH для команди.
Він також може бути використаний для запуску зовнішньої команди, затіненої командною оболонкою. Оскільки він нічого не знає про вбудовані оболонки, ключові слова, функції чи псевдоніми (все, що визначено оболонкою та оболонкою), він шукає виконувані файли в каталогах, визначених PATH
змінною оточення.
З використання системної команди замість вбудованого Bash, не вказуючи повний шлях
env
запускає виконуваний файл, названий його першим аргументом, у (можливо) модифікованому середовищі; як такий, він не знає про та не працює з вбудованими командами оболонки.
Наприклад, ця команда запустить вбудовану оболонку версії echo
:
$ echo --version
--version
З іншого боку, запуск echo
через env
виконує програму, встановлену в /usr/bin/echo
:
$ env echo --version
echo (GNU coreutils) 8.15
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Вищевказана поведінка часто використовується для використання в shebang (перший рядок) виконуваного сценарію, щоб гарантувати, що ядро використовує правильну програму для інтерпретації сценарію, - не потрібно вказувати, в якому каталозі встановлена програма інтерпретатора.
Наприклад, Python встановлюється в різних місцях в різних системах (немає стандартного місця розташування). Наступний шебанг призведе до запуску сценарію python3
програмою, доки він встановлений в одному з каталогів, зазначених у PATH
змінній оточення.
#!/usr/bin/env python3
Це використання можна перевірити в інтерактивній оболонці, ввівши в командному рядку наступне:
$ /usr/bin/env python3 --version
Python 3.2.5
З цієї чудової відповіді на тему "Як / usr / bin / env знає, яку програму використовувати?"
Ядро не хоче знати про такі змінні середовища, як
PATH
. Отже, ім'я в рядку shebang має бути абсолютним шляхом до виконуваного файлу.Основна мета
env
команди - запустити команду з іншим середовищем, але оскільки вона шукає ім'я команди в$PATH
, її можна використовувати для надання шляху команди до ядра .Хоча це офіційно не гарантовано, історичні системи Unix при умови ,
env
в/usr/bin
, і сучасні системи зберегли це місце саме через широкого використання#!/usr/bin/env
.
В основному, використання env
є більш портативним, оскільки означає, що сценарію не потрібно знати, де встановлено бажаний бінарний файл для команди запуску. Дивіться також Чому краще використовувати "#! / Usr / bin / env NAME" замість "#! / Path / to / NAME" як мій шебанг?