Различия и выполнение `set` &` env`?

задавать

set – это встроенная команда shell .

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

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

set встроенных 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 для набора.

3. Управляющее поведение оболочки

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

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

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

 set -f 

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

 set -o noglob 

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


окр

В отличие от 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 среды PATH .

From Использовать системную команду вместо встроенного 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

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

Например, Python устанавливается в разных местах на разных системах (стандартного расположения нет). Следующий shebang заставит скрипт запускаться программой python3 – до тех пор, пока он будет установлен в один из каталогов, указанных в PATH среды 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» в качестве моего shebang?

  • Как использовать строки файла в качестве аргументов команды?
  • Как настроить SSH, поэтому мне не нужно вводить пароль?
  • Определение размера кэша L2 в Linux
  • Как отсортировать первые каталоги, затем файлы и т. Д. ... при использовании «ls» в Unix
  • Поверните экран с помощью xrandr на Solaris 10
  • Powershell эквивалентен команде unix `which`?
  • Как найти самый старый файл в дереве каталогов
  • Что такое эффект CTRL + Z в приложении unix \ Linux
  • Как я могу найти историю bash и повторить команду?
  • Как я могу запустить другую команду, но с теми же аргументами?
  • Unix «$ @» в качестве параметра
  • Давайте будем гением компьютера.