Каков идиоматический способ возврата массива в функции zsh?

Я бы предложил создать и включить службуType=oneshotRemainAfterExit=yesдля пользователя, которая создает файл с помощью директивы ExecStartи удаляет его с помощью директивы ExecStop, например.

ExecStart="/usr/bin/touch %h/.decrypt"
ExecStop="/usr/bin/rm %h/.decrypt"

Затем вы можете создать и активировать файл модуля luks@xxx.pathдля системного пользователя с абсолютным путем:

PathExists="/home/user/.decrypt"

Это будет проверять путь, созданный вышеописанной пользовательской службой, активировать luks@xxx.serviceмодуль при его создании и деактивировать его при его удалении, тем самым устанавливая косвенную зависимость системной службы от пользовательской службы.

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

1
12.08.2019, 19:40
2 ответа
Встроенная функция

zshreturnможет возвращать только 32-битное целое число со знаком, как и системный вызов _exit(). Хотя это лучше, чем в большинстве других оболочек типа Bourne -, они по-прежнему не могут возвращать произвольные строки или список строк, как оболочки rc/es. Статус возврата больше связан с возвратом индикации успеха/неудачи.

Здесь, в качестве альтернативы, вы можете сделать так, чтобы функция принимала имя массива для заполнения в качестве аргумента, например:

myfunc() {
  local arrayname=$1; shift
  #...
  eval $arrayname'=("$elements[@]")'
  # the returned $? will be 0 here for success unless that eval command
  # fails.
}

myfunc myarray other args

Ваш printf '%s\0'подход не будет работать для элементов массива, содержащих значения NUL.

Вместо этого вы можете использовать флаг раскрытия параметра qqдля цитирования элементов на выходе иz(для разбора кавычек )иQ(для удаления кавычек )на входе, например:

myfunc() {
   #...
   print -r -- ${(qq)elements}
}

myarray=("${(@Q)${(z)$(myfunc)}}")

Но в дополнение к тому, что он менее разборчив, он также менее эффективен, так как означает разветвление процесса и передачу вывода myfuncчерез канал в дополнение к заключению в кавычки/раскатыванию.

8
27.01.2020, 23:15

Идиоматический способ — просто использовать массив reply. Если вы хотите, вы можете использовать флаг (P)и вернуться в массив, имя которого передается функции:

myfunc() {
  local arrayname=${1:-reply}; shift
  #...
  : ${(PA)arrayname::="${args[@]}"}
}
6
27.01.2020, 23:15

Теги

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