Как сделать так, чтобы Bash set -x применялся только к самой следующей команде без создания дочерних процессов и без вызова set +x

Это ограничено только Bash, и ответ должен работать на всех версиях Bash без исключения.

Я делаю это сейчас:

op1
(set -x; op2)
op3

и он делает то, что я ожидаю: op1 не транскрибируется, op2 транскрибируется, а затем op3 нет. И у этого есть особенность, что если происходит «заклинивание кода», из-за чего op2 имеет много строк текста, мне не нужно помнить о вызове set +x позже из-за области видимости со скобками. Я не хочу, чтобы set +x также транскрибировался, так как это загромождает вывод.

Итак, как мне сделать это без явного вызова set +x? Я пробовал фигурные скобки, но они не «отменяют» set -x, как это делают круглые скобки.

"Все версии bash без исключения"? Легко протестировать что-то до версии 3.2, которая на сегодняшний день является самой старой версией. 1.x не очень.

Charles Duffy 10.12.2020 19:53

Это непросто, если только у вас нет свободного доступа к этим старым версиям. Я вижу ваш полезный ответ, однако!

bgoodr 11.12.2020 22:46

Кстати, в сети Freenode IRC есть демон evalbot, который имеет большое количество древних версий bash в снимке виртуальной машины, который можно попросить запустить команды.

Charles Duffy 11.12.2020 23:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
135
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

За исключением случая современного 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 11.12.2020 22:47

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

Charles Duffy 11.12.2020 23:10

Понятно. Итак, пока кто-нибудь не поделится ссылкой на «доказательство» того, что дополнительные фигурные скобки необходимы, я не буду их включать. Я неоднократно искал какие-либо упоминания об использовании дополнительных фигурных скобок и ничего не нашел.

bgoodr 12.12.2020 19:35

кивок. Честно говоря, я бы не включил их, если бы вы не настаивали на ответах, которые работают для каждой возможной версии bash; существует довольно много исторических ошибок, которые влияют только на небольшой диапазон версий - некоторые профилактические методы, которым я следую, применимы только к первой второстепенной версии, чтобы ввести встроенную поддержку регулярных выражений, f/e, даже если эти версии маловероятны быть общеупотребительным в любом месте.

Charles Duffy 12.12.2020 21:03

Ага. Пересматривая свое решение: я провел некоторое время в массовом сканировании сотен хостов Linux, к которым у меня есть доступ (и это не полное сканирование, так как у меня нет прямого/быстрого доступа ко всем из них, так как многие из они блокируют соединения SSH), а диапазон версий bash варьируется от 4.1.2(1)-release до 4.4.19(1)-release. Так что, возможно, мне сошло с рук указание минимальной версии 4.1.x в описании. Если бы я не был таким строгим, я полагаю, что не получил бы такого продуманного ответа, как ваш ответ здесь.

bgoodr 15.12.2020 01:49

Другие вопросы по теме