Почему вывод «set -x» (xtrace) не подлежит перенаправлению, если он не заключен в фигурные скобки?

#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.