有人知道我们是否可以在bash中说set +x
而不打印它:
set -x
command
set +x
迹线
+ command
+ set +x
但它应该只打印
+ command
Bash是版本4.1.10(4)。现在这让我烦恼了一段时间 - 输出混乱了无用的set +x
行,使得跟踪设施没有那么有用。
答案 0 :(得分:106)
我遇到了同样的问题,我找到了一个不使用子shell的解决方案:
set -x
command
{ set +x; } 2>/dev/null
答案 1 :(得分:39)
您可以使用子shell。退出子shell后,x
的设置将丢失:
( set -x ; command )
答案 2 :(得分:7)
最近,当我对它感到恼火时,我就解决了这个问题:
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
答案 3 :(得分:3)
基于@ user108471简化版本的解决方案如何:
shopt -s expand_aliases
alias trace_on='set -x'
alias trace_off='{ set +x; } 2>/dev/null'
trace_on
...stuff...
trace_off
答案 4 :(得分:1)
这是一些想法的组合,可以封装一段代码并保留退出状态。
#!/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
答案 5 :(得分:0)
这是另一个。通常,您只想跟踪脚本中的特定命令。那为什么不写一个函数来做到这一点呢?
> call() { set -x; "$@"; { set +x; } 2>/dev/null; }
> call uname -a
+ uname -a
CYGWIN_NT-6.1-WOW W530 3.1.7(0.340/5/3) 2020-08-22 19:03 i686 Cygwin
> call make -j8 *.mak
+ make -j8 some_name.mak
我们可以通过返回(并跟踪)被调用命令的退出代码来进一步改进:
> call() { local rc; set -x; "$@"; rc=$?; { set +x; } 2>/dev/null; return $rc; }
> call true && echo yes
+ true
+ rc=0
yes
> call false && echo yes
+ false
+ rc=1
下面是一个真实的例子,它调用 Rhapsody CLI 程序从带有命令行选项的 .rcl 文件生成源代码:
die() {
local c=${1:--1} m=${2:-'Died'}
echo "$m at ${BASH_SOURCE[1]}:${FUNCNAME[1]} line ${BASH_LINENO[0]} (exit $c)" >&2
exit $c
}
call() { local rc; set -x; "$@"; rc=$?; { set +x; } 2>/dev/null; return $rc; }
call "$opt_rhapsodycl" -f $rclfile || die $? 'Rhapsody license server not reachable'
例如,在失败的情况下打印如下内容:
+ path/to/RhapsodyCL.exe -f configuration.rcl
+ rc=127
Rhapsody license server not reachable at ./Build:main line 167 (exit 127)
或者如果成功,脚本会继续。使用这两个函数(call
和 die
),我们可以编写非常紧凑且可读的单行代码,同时还可以生成良好的跟踪输出。