Answers:
使用bash4.1及更高版本,您可以执行
BASH_XTRACEFD=7 ./script.bash 7> /dev/null
(当bash作为调用时也有效sh)。
基本上,我们要在文件描述符7而不是默认值2上bash输出xtrace输出,并将该文件描述符重定向到/dev/null。fd数是任意的。使用高于2的fd,否则脚本中不会使用该fd。如果您要在其中输入此命令的shell是bash或yash,则您甚至可以使用大于9的数字(尽管如果文件描述符由shell内部使用,则可能会遇到问题)。
如果您bash从中调用该脚本的shell 是zsh,则还可以执行以下操作:
(export BASH_XTRACEFD; ./script.bash {BASH_XTRACEFD}> /dev/null)
为变量自动分配高于9的第一个自由fd。
对于较旧版本的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
另一种选择是在每个命令之前执行的$BASH_ENV文件中添加DEBUG陷阱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为脚本的路径...
{BASH_XTRACEFD}>技巧同样适用于bash4.1或更高版本。
ksh93或bash在该变量没有在命令(比较的环境中通过<shell> -c 'export fd; printenv fd {fd}> /dev/null'的zsh,bash和ksh93)。您可以分两步进行操作,也可以使用来使它在ksh93/中工作,但如果xtrace选项处于启用状态,则会产生副作用。bashevalbash
由于它们是脚本,因此您可以复制它们并进行编辑。
除此之外,过滤输出看起来很简单,您可以显式设置PS4为比单个加号更不寻常的内容,以使过滤更容易:
PS4="%%%%" bash script.sh 2>&1 | grep -ve '^%%%%'
(当然,这会使stdout和stdin崩溃,但是在Bash中仅对stderr进行管道处理会有点毛茸茸,因此我将忽略它)
PS4="%%%%" bash script.sh 2> >(grep -ve '^%%%%')。
bash有问题的,因为它grep是异步运行的(bash没有等待它,因此它可以(而且经常)在脚本中的下一个命令启动后输出东西)。
./script 2>some_file