local с подстановкой команды: почему local result=$(cmd) скрывает ошибкуВ Bash есть тонкая ловушка внутри функций. На первый взгляд эти два варианта выглядят одинаково:
result=$(false)
echo "$?"
Здесь
$? будет 1.Но если написать:
local result=$(false)
echo "$?"
получим:
0
▪️Почему так происходит
В конструкции:
local result=$(cmd)
выполняются сразу две вещи:
1. Bash выполняет
$(cmd) и получает результат.2.
local объявляет переменную.Проблема в том, что код возврата всей команды определяется
local, а не самой command substitution.local успешно создал переменную - поэтому функция видит 0.▪️Особенно неприятно с обработкой ошибок
Например:
get_data() {
local result=$(curl -fsS https://example.com/api)
echo "status=$?"
}Если
curl завершится с ошибкой, проверка $? после local может показать успешное выполнение.Ошибка потеряна.
▪️Безопасный вариант
Разделите объявление и присваивание:
get_data() {
local result
result=$(curl -fsS https://example.com/api)
local status=$?
echo "status=$status"
}Теперь
$? относится непосредственно к curl.▪️Ещё лучше - проверять сразу
get_data() {
local result
if result=$(curl -fsS https://example.com/api); then
printf '%s\n' "$result"
else
echo "command failed"
return 1
fi
}Здесь условие
if проверяет именно exit code command substitution.▪️Та же ловушка есть не только с
localПохожая ситуация возникает с некоторыми встроенными командами, когда результат присваивания объединяется с другой операцией.
Поэтому правило простое:
local result
result=$(cmd)
а не:
local result=$(cmd)
▪️Почему это важно
В обычном скрипте такая мелочь может остаться незаметной. В функции, которая используется в цепочке:
deploy || exit 1
потерянный exit code уже превращается в реальную логическую ошибку: функция может сообщить об успехе, хотя команда внутри неё завершилась с ошибкой.
BashTex 📱 #bash #linux