Значения массивов Bash как переменные внутри цикла

TL;DR

exec используется для замены текущего процесса оболочки новым и обработки перенаправления потока/дескрипторов файлов, если команда не указана. eval используется для оценки строк как команд. Оба могут использоваться для создания и выполнения команды с аргументами, известными во время выполнения, но exec заменяет процесс текущей оболочки в дополнение к выполнению команд.

exec buil-in

Синтаксис:

exec [-cl] [-a name] [command [arguments]]

Согласно мануалу, если указана команда, эта встроенная

...заменяет оболочку. Новый процесс не создается. Аргументы становятся аргументами команды.

Другими словами, если вы запускали bash с PID 1234 и запускали exec top -u root в этой оболочке, top команда будет иметь PID 1234 и заменит ваш процесс оболочки.

Где это полезно? В чем-то, известном как сценарии-оболочки. Такие сценарии создают наборы аргументов или принимают определенные решения о том, какие переменные передавать в среду, а затем используют exec для замены себя любой указанной командой и, конечно же, предоставляют те же аргументы, что и сценарий-оболочка. построенный по пути.

В руководстве также говорится следующее:

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

Это позволяет нам перенаправлять что-либо из выходных потоков текущей оболочки в файл. Это может быть полезно для регистрации или фильтрации, когда вы не хотите видеть stdout команд, а только stderr. Например, вот так:

bash-4.3$ exec 3>&1
bash-4.3$ exec > test_redirect.txt
bash-4.3$ date
bash-4.3$ echo "HELLO WORLD"
bash-4.3$ exec >&3
bash-4.3$ cat test_redirect.txt 
2017年 05月 20日 星期六 05:01:51 MDT
HELLO WORLD

Это поведение делает его удобным для регистрации в сценариях оболочки, перенаправления потоков в отдельные файлы или процессы и других забавных вещей. с файловыми дескрипторами.

На уровне исходного кода по крайней мере для bash версии 4.3 встроенный exec определен в builtins/exec.def. Он анализирует полученные команды и, если они есть, передает их функции shell_execve(), определенной в файле execute_cmd.c.

Короче говоря, существует семейство команд exec в языке программирования C, и shell_execve() по сути представляет собой функцию-оболочку для execve:

/* Call execve (), handling interpreting shell scripts, and handling
   exec failures. */
int
shell_execve (command, args, env)
     char *command;
     char **args, **env;
{

eval встроенный

В руководстве по bash 4.3 указано (выделение добавлено мной):

Аргументы считываются и объединяются в одну команду. Затем эта команда считывается и выполняется оболочкой, и ее статус выхода возвращается как значение eval.

Обратите внимание, что замены процесса не происходит.В отличие от exec, где целью является имитация функциональности execve(), встроенный eval служит только для «оценки» аргументов, как если бы пользователь набрал их в командной строке. Таким образом, создаются новые процессы.

Где это может быть полезно? Как указал Жиль в этом ответе , «... eval используется не очень часто. В некоторых оболочках наиболее распространенным использованием является получение значения переменной, имя которой неизвестно до времени выполнения». Лично я использовал его в паре скриптов на Ubuntu, где было необходимо выполнить/оценить команду на основе конкретной рабочей области, которую в данный момент использовал пользователь.

На уровне исходного кода он определен в builtins/eval.def и передает проанализированную входную строку в функцию evalstring().

Помимо прочего, eval может назначать переменные, которые остаются в текущей среде выполнения оболочки, в то время как exec не может:

$ eval x=42
$ echo $x
42
$ exec x=42
bash: exec: x=42: not found
0
10.06.2016, 09:25
0 ответов

Теги

Похожие вопросы