Изменить параметр массива внутри подоболочки

В соответствии с fedoraproject.org/wiki для загрузки в оболочку UEFI требуется «UefiShell.iso».

Since OVMF doesn't ship with any SecureBoot keys installed, we need to install some to mimic what an MS certified UEFI machine will ship with. OVMF now ships with the binaries required to set up a default set of keys. The easiest way is to use UefiShell.iso which is available at /usr/share/edk2/ovmf/UefiShell.iso. Boot your VM with this as the CD-ROM image and it should boot into the UEFI shell. At the prompt.

0
27.05.2021, 12:03
2 ответа

Весь смысл субоболочек заключается в том, чтобы выполнять часть кода в копии текущей среды исполнения оболочки(подробности см. в спецификации POSIX для sh), чтобы чтобы сохранить исходный, поэтому все дело в том, что любое изменение переменных, сделанное в подоболочке, будет потеряно после завершения подоболочки.

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

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

zshразветвляет процесс для этого, как и большинство других оболочек. Существуют исключения для оптимизации, например, когда подоболочка (...)является последней командой в скрипте zsh -c:

.
$ zsh -c 'zmodload zsh/system; echo $$; (echo $sysparams[pid]; ps; ps)'
21085
21085
    PID TTY          TIME CMD
   1839 pts/4    00:00:00 zsh
  21085 pts/4    00:00:00 zsh
  21086 pts/4    00:00:00 ps
    PID TTY          TIME CMD
   1839 pts/4    00:00:00 zsh
  21085 pts/4    00:00:00 ps

Это тот же процесс 21085, что и выше, который выполнил zsh, интерпретировал подоболочку и даже выполнил последнюю команду ps.

Достаточно установить trap, чтобы сделать эту оптимизацию недействительной, смысл в том, что это делается только в том случае, если zsh может гарантировать, что оболочка ничего не будет запускать после возврата подоболочки.

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

Если вы хотите получить значение массива, как определено подоболочкой, вам нужно, чтобы подоболочка передала свое определение родителю. Это может быть, например, через:

eval "$(
  # also a subshell using $(...)
  arr=( a b c )
  typeset -p arr
)"

Затем typesetбудет выводитьtypeset -a arr=( a b c )(или typeset -g -a arr=( a b c ), если она вызывается внутри функции ), которая после evaluации приведет к созданию той же самой переменной в родительском объекте.

Кстати, вместо:

shift arr

Я бы использовал:

shift 1 arr

или:

arr[1]=()

Фрагмент кода shift arrнеоднозначен, поскольку он означает разные вещи(shift 1 arrиshift arr argv)в зависимости от того, объявлено ли arrкак переменная массива или нет. Использование shift 1 arrделает более очевидным, что вам нужно первое.

2
28.07.2021, 11:28

Подоболочка — это другой процесс, он не может модифицировать родительский процесс.

2
28.07.2021, 11:28

Теги

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