Если кто-то столкнется с этой проблемой в будущем, вот как я ее решил. Я только что использовал gmux_backlight +50000
, и это сработало отлично.
С bash
4.1 и выше, вы можете сделать
BASH_XTRACEFD=7 ./script.bash 7> /dev/null
(также работает, когда bash
вызывается как sh
).
По сути, мы говорим bash
выводить вывод xtrace
на файловый дескриптор 7 вместо 2 по умолчанию, и перенаправлять этот файловый дескриптор на /dev/null
. Номер fd является произвольным. Используйте fd больше 2, который не используется в вашем сценарии. Если оболочка, в которой вы вводите эту команду, bash
или yash
, вы можете даже использовать число больше 9 (хотя вы можете столкнуться с проблемами, если дескриптор файла используется внутри оболочки).
Если оболочка, из которой вы вызываете сценарий bash
, - zsh
, вы также можете сделать:
(export BASH_XTRACEFD; ./script.bash {BASH_XTRACEFD}> /dev/null)
чтобы переменной автоматически присваивалось первое свободное fd больше 9.
Для старых версий bash
, другой вариант, если xtrace
включен с помощью set -x
(в отличие от #! /bin/bash -x
или set -o xtrace
) было бы переопределить set
как экспортируемую функцию, которая ничего не делает при передаче -x
(хотя это сломает скрипт, если он (или любой другой скрипт bash
, который он вызывает) использует set
для установки позиционных параметров).
Например:
set()
case $1 in
(-x) return 0;;
(-[!-]|"") builtin set "$@";;
(*) echo >&2 That was a bad idea, try something else; builtin set "$@";;
esac
export -f set
./script.bash
Другой вариант - добавить ловушку DEBUG в файл $BASH_ENV
, который делает set +x
перед каждой командой.
echo 'trap "{ set +x; } 2>/dev/null" DEBUG' > ~/.no-xtrace
BASH_ENV=~/.no-xtrace ./script.bash
Однако это не будет работать, когда set -x
выполняется во вложенной оболочке.
Как сказал @ilkkachu, если у вас есть права на запись в любую папку в файловой системе, вы должны иметь возможность сделать копию скрипта и отредактировать его.
Если вам некуда записать копию скрипта, или если вам не удобно создавать и редактировать новую копию каждый раз, когда происходит обновление оригинального скрипта, вы все равно сможете это сделать:
bash <(sed 's/set -x/set +x/g' ./script.bash)
Этот способ (и способ копирования) может работать неправильно, если скрипт делает что-нибудь причудливое с $0
или специальными переменными типа $BASH_SOURCE
(например, ищет файлы, относительные к расположению самого скрипта), поэтому вам может понадобиться дополнительное редактирование, например, заменить $0
на путь к скрипту. ..
Поскольку это скрипты, вы могли бы сделать их копии и отредактировать их.
В остальном, фильтрация вывода кажется простой, вы можете явно установить PS4
на что-то более необычное, чем один плюс, чтобы облегчить фильтрацию:
PS4="%%%%" bash script.sh 2>&1 | grep -ve '^%%%%'
(конечно, это приведет к разрушению stdout и stdin, но использование только stderr в Bash становится немного неприятным, поэтому я проигнорирую это)