Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何让Bash set-x只应用于下一个命令,而不创建子进程,也不调用set+;x_Linux_Bash_Shell - Fatal编程技术网

Linux 如何让Bash set-x只应用于下一个命令,而不创建子进程,也不调用set+;x

Linux 如何让Bash set-x只应用于下一个命令,而不创建子进程,也不调用set+;x,linux,bash,shell,Linux,Bash,Shell,这仅限于Bash,答案需要毫无例外地适用于所有Bash版本 我现在这样做: op1 (set -x; op2) op3 它实现了我所期望的:op1没有被转录,op2被转录,然后op3没有被转录。它的特点是,如果发生“代码楔入”,op2有很多行文本,我就不必记得稍后调用set+x,因为括号中有范围。我不希望set+x也被转录,因为它会使输出变得混乱 那么,如何在不显式调用set+x的情况下执行上述操作呢?我尝试过使用花括号,但它们不会像括号那样“撤消”set-x。除了现代bash 4.x的默认关

这仅限于Bash,答案需要毫无例外地适用于所有Bash版本

我现在这样做:

op1
(set -x; op2)
op3
它实现了我所期望的:
op1
没有被转录,
op2
被转录,然后
op3
没有被转录。它的特点是,如果发生“代码楔入”,op2有很多行文本,我就不必记得稍后调用
set+x
,因为括号中有范围。我不希望
set+x
也被转录,因为它会使输出变得混乱


那么,如何在不显式调用
set+x
的情况下执行上述操作呢?我尝试过使用花括号,但它们不会像括号那样“撤消”set-x。

除了现代bash 4.x的默认关闭bash\u XTRACEFD功能处于活动状态外,以下功能可以正常工作:

logged_cmd() {
  local rc=0
  set -x
  "$@"
  { { rc=$?; set +x; }; } 2>/dev/null
  return "$rc"
}

op1
logged_cmd op2
op3

添加对正在使用bashxtracefd的情况的支持(导致
set-x
日志转到stderr以外的其他地方)将需要使用BASH 4.1+功能,这在问题中被明确禁止。

所有BASH版本无例外?测试3.2版本很容易,这是目前使用的最旧版本。1.x,没有那么多。这并不容易,除非你可以轻松访问那些旧版本。不过,我确实看到你的脸了!顺便说一句,在Freenode IRC网络中有一个
evalbot
守护进程,它在VM快照中有各种各样的古老bash版本,您可以要求它在其中运行命令。答案非常有用。你能解释一下为什么这里需要额外的一层花括号吗?在我当前的Bash版本中,如果我去掉外部的两个花括号,它似乎仍然有效。例如,这个:
{rc=$?;set+x;}2>/dev/null
@bgoodr,我不想在shell中引发货物崇拜问题,但唉,我不记得具体的细节,不知道什么时候需要。明白了。所以,现在,除非有人能分享一个“证据”,证明需要额外的大括号,否则我不会把它们包括在内。我已经反复搜寻任何关于额外支架使用的信息,结果都是空的。点头。老实说,如果你没有坚持对bash的每个可能版本都有效的答案,我就不会把它们包括在内;有相当多的历史错误只影响一小部分版本范围——我遵循的一些预防措施只适用于引入本机正则表达式支持f/e的第一个次要版本,即使这些版本不太可能在任何地方通用。是的。重新考虑我的决定:我花了一些时间对我访问过的数百台Linux主机进行了大规模扫描(这不是一次完整的扫描,因为我无法直接/快速访问所有主机,因为其中许多主机会阻止SSH连接),bash版本的范围从
4.1.2(1)-release
4.4.19(1)-release
。因此,我可能在描述中提前声明了4.1.x的最低版本,从而逃脱了惩罚。如果我没有那么严格,我想我不会得到像你在这里的回答那样深思熟虑的回答。