有谁知道我们是否可以set +x
不打印而使用bash 发言:
set -x
command
set +x
痕迹
+ command
+ set +x
但它应该只是打印
+ command
Bash是版本4.1.10(4)。现在,这困扰了我一段时间-输出杂乱无章的set +x
行,使跟踪功能无法发挥应有的作用。
有谁知道我们是否可以set +x
不打印而使用bash 发言:
set -x
command
set +x
痕迹
+ command
+ set +x
但它应该只是打印
+ command
Bash是版本4.1.10(4)。现在,这困扰了我一段时间-输出杂乱无章的set +x
行,使跟踪功能无法发挥应有的作用。
Answers:
我遇到了同样的问题,并且能够找到不使用子外壳的解决方案:
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通常是好的样式的原因。但是shell的set -x
跟踪处理就很好,因此在这里可以完美地工作,并且确实使这个咒语变得更短。
您可以使用子外壳。退出子Shell时,设置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
您将获得如下所示的输出:
$ ./script.sh one two
+ ARG1=one
+ ARG2=two
/dev/stdin
部分)。需要注意的是,在脚本中打开别名扩展会产生有害的副作用。
/dev/stdin
。我不知道任何特定的副作用,因为非交互式环境不应加载任何定义别名的文件。可能会有什么副作用?
set +x
很难(即使不是不可能)妥协。但这仍然是一个好的直接解决方案-可能是迄今为止最好的解决方案。
这是一些想法的组合,可以封装一段代码并保留退出状态。
#!/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
执行时:
$ ./test.sh
+ echo hello
hello
status: 0
+ exit 56
status: 56
()
周围exit
没有必要。好。也许这就是偏执,但如果这个代码在一般的使用你有一个不错的攻击向量:重新定义trace_on
和trace_off
并注入代码读取执行的命令。如果仅使用此类“实用程序”,则具有启发性,但是如果将代码与其他人一起使用,则必须考虑这种非标准化功能的好处是否胜过缺点。我个人{ set +x; } 2>/dev/null
对此很满意,因为这种结构是众所周知的,并且也不会改变退出状态。
script.sh 2>&1 | grep -v 'set +x'