Кто-нибудь знает, можем ли мы сказать set +x
в bash без его печати:
set -x
command
set +x
следы
+ command
+ set +x
но он должен просто напечатать
+ command
Bash - это версия 4.1.10 (4). Это меня уже некоторое время беспокоит - вывод загроможден бесполезными set +x
строками, что делает средство трассировки не таким полезным, как могло бы быть.
script.sh 2>&1 | grep -v 'set +x'
Ответы:
У меня была такая же проблема, и я смог найти решение, в котором не используется подоболочка:
set -x command { set +x; } 2>/dev/null
источник
set +x
такая успешная командаcommand
, это изменение является решением:{ STATUS=$?; set +x; } 2>/dev/null
. Затем$STATUS
на досуге просмотрите следующие строки.{ set +x; } 2>&-
. Это полностью закрывает fd 2, а не указывает на / dev / null. Некоторые программы не справляются с такой задачей при попытке печати в stderr, поэтому / dev / null в целом - хороший стиль; ноset -x
трассировка оболочки прекрасно справляется с этим, так что здесь она отлично работает и делает это заклинание немного короче.Вы можете использовать подоболочку. После выхода из подоболочки настройка
x
будет потеряна:( set -x ; command )
источник
( set -x \n command \n )
может быть хужеset -x \n command \n set +x
.cd
: он не меняет текущий каталог в родительской оболочке.Совсем недавно я взломал решение этой проблемы, когда меня это рассердило:
shopt -s expand_aliases _xtrace() { case $1 in on) set -x ;; off) set +x ;; esac } alias xtrace='{ _xtrace $(cat); } 2>/dev/null <<<'
Это позволяет включать и отключать xtrace, как показано ниже, где я регистрирую, как аргументы назначаются переменным:
xtrace on ARG1=$1 ARG2=$2 xtrace off
И вы получите результат, который выглядит так:
источник
/dev/stdin
роль). Предостережение заключается в том, что включение раскрытия псевдонимов в скриптах может иметь нежелательные побочные эффекты./dev/stdin
. Мне не известны какие-либо конкретные побочные эффекты, поскольку неинтерактивная среда не должна загружать файлы, определяющие псевдонимы. Какие могут быть побочные эффекты?set +x
гораздо труднее (если не невозможно) пойти на компромисс. Но это по-прежнему хорошее и прямое решение - возможно, лучшее на данный момент.Как насчет решения на основе упрощенной версии @ user108471:
shopt -s expand_aliases alias trace_on='set -x' alias trace_off='{ set +x; } 2>/dev/null' trace_on ...stuff... trace_off
источник
function () { set_plus_x='{ set +x; } 2>/dev/null' }
Это комбинация нескольких идей, которые могут заключить блок кода и сохранить статус выхода.
#!/bin/bash shopt -s expand_aliases alias trace_on='set -x' alias trace_off='{ PREV_STATUS=$? ; set +x; } 2>/dev/null; (exit $PREV_STATUS)' trace_on echo hello trace_off echo "status: $?" trace_on (exit 56) trace_off echo "status: $?"
При исполнении:
$ ./test.sh + echo hello hello status: 0 + exit 56 status: 56
источник
()
вокругexit
нет необходимости. ОК. Может быть, параноик, но если этот код используется в основном у вас есть вектор хорошей атаки: Переопределитьtrace_on
иtrace_off
и ввести код , который считывает команду выполняется. Если вы используете только такие «утилиты», это поучительно, но если код используется с другими, вы должны подумать, перевешивают ли преимущества таких нестандартных функций недостатки. Лично я смирился, так{ set +x; } 2>/dev/null
как эта конструкция обычно понимается и тоже не меняет статус выхода.()
всегоexit 56
; это было просто для того, чтобы я мог продемонстрировать, что статус выхода подпроцесса доступен в сценарии bash; без скобок он не стал бы подпроцессом, и в этот момент скрипт завершился бы со статусом = 65.