• В чем разница между командами set и env ?

  • Когда будет / должен быть использован один в отличие от другого?

  • Как они вообще вызваны? (Типичное использование; сценарий случая).

1 ответ1

2

задавать

set - это встроенная команда оболочки .

(Поскольку этот вопрос помечен как оболочка Unix, я опускаю команду MS Windows.)

Спецификация POSIX

Встроенный set определен в POSIX с рядом функций.

1. Позиционные параметры

Основная цель встроенного set состоит в том, чтобы

установить или сбросить параметры и позиционные параметры.

Позиционные параметры передаются в оболочку (обычно это скрипт, но может быть интерактивным) в качестве аргументов вызывающей программой - обычно (но не обязательно) другой оболочкой. Первый параметр доступен как $1 , второй как $2 и т.д.

Команда set может управлять этими параметрами. Каждый переданный ему аргумент устанавливается как позиционный параметр, например

$ set one two
$ echo "$1"
one
$ echo "$2"
two

set -- отменяет все позиционные параметры:

$ set --
$ echo $1   # no output

2. Перечислите переменные оболочки

Тем не менее, спецификация 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.

3. Контроль поведения оболочки

set также используется для управления атрибутами оболочки, обычно (но не обязательно) интерактивной оболочки. Это делается путем запуска его с определенными предопределенными параметрами (чтобы отличить их от аргументов, которые используются для установки позиционных параметров, как описано выше).

Когда параметры указаны, они должны устанавливать или отменять атрибуты оболочки

Эти параметры подробно описаны в спецификации POSIX. Одним из примеров является

set -f

Опция -f отключает выполнение расширения (глобализация) пути текущей оболочкой. Это поведение также можно настроить с помощью эквивалентной команды:

set -o noglob

Такие оболочки, как Bash, расширяются в этом списке и включают такие параметры, как -B (или -o braceexpand); это включает расширение скобки (только для Bash) в текущей оболочке.


окр

В отличие от set , команда env является обычной внешней командой, то есть она не является частью оболочки. По соглашению (для переносимости) в каждой среде Unix программа env представляет собой исполняемый файл, установленный в каталог /usr/bin .

Спецификация POSIX

Инструмент env также определяется POSIX.

1. Изменить среду команды

Основная цель команды 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

2. Переменные среды печати

Если команда не указана, печатается текущая среда.

$ 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 .

3. Поиск PATH для запуска установленной программы

Другое использование 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.

4. Сценарий шебанг

Вышеупомянутое поведение часто используется для использования в shebang (первая строка) исполняемого скрипта, чтобы гарантировать, что ядро использует правильную программу для интерпретации скрипта - без необходимости указывать, в какой каталог была установлена программа интерпретатора.

Например, Python устанавливается в разных местах в разных системах (стандартного расположения нет). Следующий shebang приведет к запуску сценария программой 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 »вместо« #!/ путь / к / ИМЯ »как мой шебанг?

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .