Из "man Bash":
Параметр установлен, если ему присвоено значение. Нулевая строка является допустимым значением. После того, как переменная установлена, ее можно снять только с помощью встроенной команды unset.
Когда вы делаете testing2=
, вы устанавливаете переменную в нулевую строку.
Измените это на unset testing2
и попробуйте снова.
В этом случае set -e
не поможет, так как присваивание никогда не имеет кода выхода 1. Попробуйте сделать это, чтобы увидеть, что последняя выполненная команда (присваивание) имеет код выхода 0, или прочитайте этот вопрос:
$ false; a=""; echo $?
0
И я также считаю, что использование set -e скорее проблема, чем решение.
Что может привести к ошибке при использовании переменных без установки, так это set -u
:
#!/bin/bash
set -u
testing="This works"
echo ${testing}
unset testing2
echo ${testing2}
testing3="This should not appear"
echo ${testing3}
Будет выведено:
$ ./script.sh
This works
./script.sh: line 9: testing2: unbound variable
Это диагностическое сообщение генерируется системой управления заданиями интерактивной оболочки, для удобства пользователя -оно не связано с ошибкой базовой программы. Когда вы передаете функцию оболочки, для запуска функции создается подоболочка , и эта подоболочка не рассматривается как обращенная к пользователю -. Если вы вызываете функцию в обычном режиме, она запускается в исходной оболочке, и сообщение печатается.
Вы можете проверить это, отключив управление заданиями в текущей оболочке
set +m
, а затем снова запустив ./binary
:, теперь он тоже ничего не печатает. По -включите управление заданиями с помощью set -m
.
Даже голая подоболочка имеет тот же эффект:
( : ;./binary )
не будет печатать диагностику (здесь требуются две команды, чтобы избежать подоболочки -игнорирования оптимизации ). Вывод из функции тоже делает это.
Управление заданиями отключено в подоболочке, и даже если оно включено вручную, оно отключается. Это досадный пробел в системе. В не -интерактивной оболочке сообщение всегда будет передаваться через другой механизм, и в любом другом месте в интерактивной оболочке это будет так же.
Если печать диагностики важна для вас, создание сценария вместо функции позволит вам убедиться, что он всегда включен. Поскольку вы используете функцию в конвейере, вы все равно не можете делать ничего, что требует функции, поэтому это не требует больших затрат.
Я бы не сказал, что это ошибка. Одна из возможных причин такого поведения — заставить подстановку команд $(...)
, которая также запускает подоболочку, вести себя соответствующим образом:
foo=$(echo|test)
не должно приводить к сохранению диагностического сообщения в foo
, чтобы сбои конвейера приводили к пустым расширениям. Другой способ — намеренно временно подавить диагностические сообщения.