Это ограничено только Bash, и ответ должен работать на всех версиях Bash без исключения.
Я делаю это сейчас:
op1
(set -x; op2)
op3
и он делает то, что я ожидаю: op1
не транскрибируется, op2
транскрибируется, а затем op3
нет. И у этого есть особенность, что если происходит «заклинивание кода», из-за чего op2 имеет много строк текста, мне не нужно помнить о вызове set +x
позже из-за области видимости со скобками. Я не хочу, чтобы set +x
также транскрибировался, так как это загромождает вывод.
Итак, как мне сделать это без явного вызова set +x
? Я пробовал фигурные скобки, но они не «отменяют» set -x
, как это делают круглые скобки.
Это непросто, если только у вас нет свободного доступа к этим старым версиям. Я вижу ваш полезный ответ, однако!
Кстати, в сети Freenode IRC есть демон evalbot
, который имеет большое количество древних версий bash в снимке виртуальной машины, который можно попросить запустить команды.
За исключением случая современного bash 4.x с активно используемой функцией BASH_XTRACEFD по умолчанию, следующее будет работать нормально:
logged_cmd() {
local rc=0
set -x
"$@"
{ { rc=$?; set +x; }; } 2>/dev/null
return "$rc"
}
op1
logged_cmd op2
op3
Добавление поддержки для случаев, когда используется BASH_XTRACEFD (чтобы журналы set -x
отправлялись куда-то, кроме stderr), потребует использования функций bash 4.1+, что было явно запрещено в вопросе.
Очень полезный ответ. Не могли бы вы пояснить, зачем здесь нужен дополнительный слой фигурных скобок? В моей текущей версии Bash, если я уберу две внешние фигурные скобки, это все равно будет работать. Например, это: { rc=$?; set +x; } 2>/dev/null
@bgoodr, я ненавижу вносить свой вклад в проблему карго-культа в оболочке, но, увы, я не помню подробностей, когда именно это необходимо.
Понятно. Итак, пока кто-нибудь не поделится ссылкой на «доказательство» того, что дополнительные фигурные скобки необходимы, я не буду их включать. Я неоднократно искал какие-либо упоминания об использовании дополнительных фигурных скобок и ничего не нашел.
кивок. Честно говоря, я бы не включил их, если бы вы не настаивали на ответах, которые работают для каждой возможной версии bash; существует довольно много исторических ошибок, которые влияют только на небольшой диапазон версий - некоторые профилактические методы, которым я следую, применимы только к первой второстепенной версии, чтобы ввести встроенную поддержку регулярных выражений, f/e, даже если эти версии маловероятны быть общеупотребительным в любом месте.
Ага. Пересматривая свое решение: я провел некоторое время в массовом сканировании сотен хостов Linux, к которым у меня есть доступ (и это не полное сканирование, так как у меня нет прямого/быстрого доступа ко всем из них, так как многие из они блокируют соединения SSH), а диапазон версий bash варьируется от 4.1.2(1)-release
до 4.4.19(1)-release
. Так что, возможно, мне сошло с рук указание минимальной версии 4.1.x в описании. Если бы я не был таким строгим, я полагаю, что не получил бы такого продуманного ответа, как ваш ответ здесь.
"Все версии bash без исключения"? Легко протестировать что-то до версии 3.2, которая на сегодняшний день является самой старой версией. 1.x не очень.