В соответствии с 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.
Весь смысл субоболочек заключается в том, чтобы выполнять часть кода в копии текущей среды исполнения оболочки(подробности см. в спецификации 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 )
, если она вызывается внутри функции ), которая после eval
uации приведет к созданию той же самой переменной в родительском объекте.
Кстати, вместо:
shift arr
Я бы использовал:
shift 1 arr
или:
arr[1]=()
Фрагмент кода shift arr
неоднозначен, поскольку он означает разные вещи(shift 1 arr
иshift arr argv
)в зависимости от того, объявлено ли arr
как переменная массива или нет. Использование shift 1 arr
делает более очевидным, что вам нужно первое.
Подоболочка — это другой процесс, он не может модифицировать родительский процесс.