Як змусити `локальний` захопити вихідний код?


11

У моєму проекті є такий фрагмент:

local output="$(bash "${1##*/}")"
echo "$?"

Це завжди друкує нуль через local, однак, видалення localпризводить до того, що $?змінна поводиться правильно: що полягає у припущенні коду виходу з нижньої частини.

Моє запитання: як я можу зберегти цю змінну локальної, в той же час фіксуючи значення виходу?


1
shellcheckне тільки вирішить це питання, але запропонує вирішити на unix.stackexchange.com/a/281749/24718 !
Уелі Хан

Відповіді:


16
#!/bin/bash
thing() {
   local foo=$(asjkdh) ret="$?"
   echo "$ret"
}

Це буде лунати 127, правильний код помилки для "команди не знайдено".

Ви можете використовувати localдля визначення декількох змінних. Тож я просто створюю локальну змінну, RETщоб захопити вихідний код підпакеті перед тим, як localдосягти успіху і встановити $?нуль.


Чи гарантується, що bashоцінює цей вираз зліва направо?
Макс Рійд

Наскільки мені відомо, змінні призначення в порядку, зліва направо в цьому контексті, так.
DopeGhoti

@MaxRied той факт, що це працює надійно, мабуть, свідчить про те, що так. Однак я не можу знайти жодної інформації про це, ні з POSIX, ні bashз довідкового посібника.
кіт

10
В бік використання імен змінних all-caps - це погана форма. Див. Специфікацію змінної середовища POSIX на веб- сайті pubs.opengroup.org/onlinepubs/009695399/basedefs/… , яка описує імена верхнього регістру як зарезервовані для змінних зі значенням оболонки або системи та імена, що мають принаймні один нижній регістр символів зарезервовано для використання, визначеного додатком, маючи на увазі, що змінні оболонки та змінні середовища мають спільний простір імен (оскільки, у випадку зіткнень, присвоєння першому може змінити останнє).
Чарльз Даффі

Коментарі не для розширеного обговорення; ця розмова була переміщена до чату .
тердон

27

Декларуйте локальну змінну, перш ніж призначити її:

thing() {
  local output
  output="$(bash "${1##*/}")"
  echo "$?"
}

На мою думку, це також легше читати, ніж встановлювати додаткову RETзмінну. YMMV щодо цього, але він працює так, як ви очікували.


2
Це набагато краще, ніж використання окремої змінної, як це повинно бути очевидно, якщо ви хочете перевірити код повернення кількох призначень: просто local var1 var2 ...і дядька Боба.
l0b0

@ l0b0 Боб - мій дядько. : D
кіт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.