Ошибка обновления Debian 7 (wheezy) до 8 (jessie), plymouth 0.9.0-9 наполовину настроен

eval и exec - совершенно разные звери. (Кроме того факта, что оба выполняют команды, но и все, что вы делаете в оболочке)

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

То, что делает exec cmd, точно такое же, как просто запуск cmd, за исключением того, что текущая оболочка заменяется командой, а не запускается отдельный процесс. Внутренне, запуск, скажем, /bin/ls вызовет fork() для создания дочернего процесса, а затем exec() в дочернем процессе для выполнения /bin/ls. exec /bin/ls, с другой стороны, не форк, а просто заменяет оболочку.

Сравните:

$ bash -c 'echo $$ ; ls -l /proc/self ; echo foo'
7218
lrwxrwxrwx 1 root root 0 Jun 30 16:49 /proc/self -> 7219
foo

с

$ bash -c 'echo $$ ; exec ls -l /proc/self ; echo foo'
7217
lrwxrwxrwx 1 root root 0 Jun 30 16:49 /proc/self -> 7217

echo $$ выводит PID запущенной оболочки, а листинг /proc/self дает нам PID ls, который был запущен из оболочки. Обычно идентификаторы процессов отличаются, но в случае с exec shell и ls имеют один и тот же идентификатор процесса. Кроме того, команда, следующая за exec, не выполнялась, поскольку оболочка была заменена.


С другой стороны:

$ help eval
eval: eval [arg ...]
    Execute arguments as a shell command.

eval запустит аргументы как команду в текущей оболочке. Другими словами, eval foo bar - это то же самое, что просто foo bar. Но переменные будут расширены перед выполнением, поэтому мы можем выполнять команды, сохраненные в переменных оболочки:

$ unset bar
$ cmd="bar=foo"
$ eval "$cmd"
$ echo "$bar"
foo

Это не создаст дочерний процесс, поэтому переменная устанавливается в текущей оболочке. (Конечно, eval /bin/ls создаст дочерний процесс, так же как и старый добрый /bin/ls.)

Или мы можем иметь команду, которая выводит команды оболочки. Выполнение ssh-agent запускает агента в фоновом режиме и выводит кучу назначений переменных, которые могут быть установлены в текущей оболочке и использованы дочерними процессами (команды ssh, которые вы бы запустили). Следовательно, ssh-agent может быть запущен с помощью:

eval $(ssh-agent)

И текущая оболочка получит переменные для наследования другими командами.


Конечно, если переменная cmd будет содержать что-то вроде rm -rf $HOME, то выполнение eval "$cmd" не будет тем, что вы захотите сделать. Даже такие вещи, как подстановки команд внутри строки, будут обработаны, поэтому следует действительно убедиться, что входные данные для eval безопасны, прежде чем использовать его.

Часто можно избежать eval и даже случайно не смешать код и данные неправильным образом.

3
27.02.2017, 13:11
1 ответ

Bug780443 кажется вашей проблемой. Вкратце, кто-то решил запустить:

apt dist-upgrade udev plymouth

Я также нашел это : предлагаемое решение - установить пакет upgrade-system для обновления с Wheezy до Jessie с помощью команды upgrade -система .

1
27.01.2020, 21:21

Теги

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