Выходной сигнал ошибки сегментации подавляется при передаче stdin функции по конвейеру. Почему?

Из "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

6
13.04.2019, 23:38
1 ответ

Это диагностическое сообщение генерируется системой управления заданиями интерактивной оболочки, для удобства пользователя -оно не связано с ошибкой базовой программы. Когда вы передаете функцию оболочки, для запуска функции создается подоболочка , и эта подоболочка не рассматривается как обращенная к пользователю -. Если вы вызываете функцию в обычном режиме, она запускается в исходной оболочке, и сообщение печатается.

Вы можете проверить это, отключив управление заданиями в текущей оболочке

set +m

, а затем снова запустив ./binary:, теперь он тоже ничего не печатает. По -включите управление заданиями с помощью set -m.

Даже голая подоболочка имеет тот же эффект:

( : ;./binary )

не будет печатать диагностику (здесь требуются две команды, чтобы избежать подоболочки -игнорирования оптимизации ). Вывод из функции тоже делает это.

Управление заданиями отключено в подоболочке, и даже если оно включено вручную, оно отключается. Это досадный пробел в системе. В не -интерактивной оболочке сообщение всегда будет передаваться через другой механизм, и в любом другом месте в интерактивной оболочке это будет так же.


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


Я бы не сказал, что это ошибка. Одна из возможных причин такого поведения — заставить подстановку команд $(...), которая также запускает подоболочку, вести себя соответствующим образом:

foo=$(echo|test)

не должно приводить к сохранению диагностического сообщения в foo, чтобы сбои конвейера приводили к пустым расширениям. Другой способ — намеренно временно подавить диагностические сообщения.

7
27.01.2020, 20:27

Теги

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