Отличить и выполнить `set` & `env`?
В чем разница между
set
а такжеenv
команды?Когда будет / должен быть использован один в отличие от другого?
Как они вообще вызваны? (Типичное использование; сценарий случая).
1 ответ
задавать
set
is a shell builtin command.
(Since this question is tagged as Unix shells, I'm omitting the MS Windows command.)
POSIX specification
set
builtin is defined in POSIX with a number of features.
1. Positional parameters
The primary purpose of the set
builtin is to
set or unset options and positional parameters.
Positional parameters are passed to the shell (usually a script – but can be interactive) as arguments by the calling program – usually (but not necessarily) another shell. The first parameter is available as $1
, the second as $2
, так далее.
set
command can manipulate these parameters. Each argument supplied to it is set to be a positional parameter, eg
$ set one two
$ echo "$1"
one
$ echo "$2"
two
set --
unsets all positional parameters:
$ set --
$ echo $1 # no output
2. List shell variables
However, the POSIX specification also describes other uses for set
:
Бег set
by itself prints the names and values of all shell variables. Это включает
- all shell variables set within the current shell and
- all environment variables inherited from its parent process.
Пример:
$ 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'
In the above listing, HOME
, LANG
а также PATH
are environment variables while IFS
а также PS1
в PS4
are all shell variables that have been set in the current shell.
Note: In the Bash shell, the set
builtin also prints the definitions of shell functions. For more info, see the Bash manual for set.
3. Control behaviour of the shell
set
is also used to control the attributes of the shell, usually (but not necessarily) an interactive shell. This is done by running it with certain pre-defined options (to distinguish them from arguments that are used to set positional parameters as described above).
When options are specified, they shall set or unset attributes of the shell
These options are detailed in the POSIX specification. Одним из примеров является
set -f
-f
option disables pathname expansion (globbing) from being carried out by the current shell. This behaviour can also be configured with the equivalent command:
set -o noglob
Shells such as Bash expand on this list to include options such as -B
(или же -o braceexpand
); this turns on brace expansion (a Bash-only features) in the current shell.
окр
В отличие от set
, env
command is a regular external command, ie, it's not part of the shell. By convention (for portability), on every Unix environment the env
program is an executable file installed into the /usr/bin
каталог.
POSIX specification
env
tool is also specified by POSIX.
1. Modify the environment of a command
The primary purpose of the env
command is to run a command with a different/modified environment.
env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
The following example runs the git status
command with two environment variables set:
env GIT_DIR=~/notes/.git/ GIT_WORK_TREE=~/notes/ git status
-i
вариант с env
can be used to run a command with an empty environment, ie, no environment variables are inherited from the parent process.
Note that if only modifying one or two environment variables and using the Bash shell, there's no need for env
as Bash itself can already temporarily modify the environment for one command. In Bash, the above example could have been simply run as:
GIT_DIR=~/notes/.git/ GIT_WORK_TREE=~/notes/ git status
2. Print environment variables
If no command is provided, the current environment is printed.
$ 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
Note that this only prints environment variables – not shell variables such as PS1
или же IFS
,
3. Search the PATH to run an installed program
Another use of env
is to search the PATH for a command.
It can also be used to run an external command that is shadowed by a shell-specific command. Since it knows nothing about shell builtins, keywords, functions or aliases (anything defined by the shell and for the shell), it search for executable files in the directories specified by the PATH
переменная окружения.
From Use system command instead of Bash builtin without specifying the full path
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 устанавливается в разных местах в разных системах (стандартного расположения нет). Следующий шебанг приведет к запуску скрипта 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" в качестве моего шебанга?