#bash
#bash
Вопрос:
Я включаю повторное воспроизведение команд в скрипте bash, используя «set -x». Когда я отключаю эхо-отображение, я выдаю «set x», но я не хочу, чтобы эта команда повторялась. Для этого я выдаю команду:
{ set x; } 2>/dev/null
Это работает нормально. Однако я не совсем понимаю, почему это работает, а следующее — нет:
set x 2>/dev/null
Очевидно, что эхо команды не передается в stderr, но я не совсем понимаю, почему работает команда с точкой с запятой в фигурных скобках.
Ответ №1:
Причина, по которой вам нужно использовать фигурные скобки, заключается в том, что xtrace
протоколирование ( set x
строка, которую вы пытаетесь подавить) не выводится из самой команды set x
(команда, которая сама по себе ничего не записывает ни в stderr , ни в stdout). Вместо этого он выводится из вызывающей оболочки set x
.
При запуске set x 2>/dev/null
это перенаправляет stderr на /dev/null
только для выполнения set x
самого. Он не перенаправляет действия, выполняемые оболочкой при настройке для выполнения этой команды, которая включает печать журналов трассировки.
В отличие от этого, при запуске { set x; } 2>/dev/null
перенаправление выполняется перед запуском всего блока кода, который по своей природе включает предварительную настройку команды для каждой команды в этом блоке. Таким образом, настройка для команды выполняется также в перенаправленной среде.
Вы бы не хотели, чтобы было иначе — какая была бы польза, set -x
если someprogram 2>/dev/null
вообще не регистрировать, что он был вызван someprogram
?
Кстати, это очень похоже на то, почему вывод встроенной в оболочку time
команды не подлежит перенаправлению, если не заключен в более широкий контекст; подробнее об этом см. BashFAQ #32.