Chr*_*ian 36 bash shell command-line bash-scripting jenkins
我正在运行 Jenkins 的 shell 脚本,它使用 shebang options 启动 shell 脚本#!/bin/sh -ex
。
根据Bash Shebang 的假人?, -x
, “导致 shell 打印执行跟踪”,这对于大多数用途都非常有用——除了回声:
echo "Message"
Run Code Online (Sandbox Code Playgroud)
产生输出
+ echo "Message"
Message
Run Code Online (Sandbox Code Playgroud)
这有点多余,看起来有点奇怪。有没有办法保持-x
启用,但只输出
Message
Run Code Online (Sandbox Code Playgroud)
而不是上面的两行,例如通过在 echo 命令前加上一个特殊的命令字符,或者重定向输出?
G-M*_*ca' 33
当您在短吻鳄的脖子上时,很容易忘记目标是排干沼泽。?????????????????? ——流行的说法
问题是关于echo
,但到目前为止,大多数答案都集中在如何潜入set?+x
命令上。有一个更简单、更直接的解决方案:
{ echo "Message"; } 2> /dev/null
Run Code Online (Sandbox Code Playgroud)
(我承认,{ …; } 2> /dev/null
如果我没有在之前的答案中看到它,我可能不会想到它。)
这有点麻烦,但是,如果您有一组连续的echo
命令,则无需对每个命令单独执行:
{
echo "The quick brown fox"
echo "jumps over the lazy dog."
} 2> /dev/null
Run Code Online (Sandbox Code Playgroud)
请注意,有换行符时不需要分号。
您可以减少使用打字负担kenorb的想法
开放的/dev/null
一个非标准的文件描述符永久性地(例如3),然后说2>&3
,而不是2>?/dev/null
所有的时间。
撰写本文时的前四个答案需要在
每次执行echo
. 如果您真的希望所有 echo
命令都抑制执行跟踪(为什么不呢?),您可以全局执行此操作,而无需修改大量代码。首先,我注意到没有跟踪别名:
$ myfunc()
> {
> date
> }
$ alias myalias="date"
$ set -x
$ date
+ date
Mon, Oct 31, 2016 0:00:00 AM # Happy Halloween!
$ myfunc
+ myfunc # Note that function call is traced.
+ date
Mon, Oct 31, 2016 0:00:01 AM
$ myalias
+ date # Note that it doesn’t say + myalias
Mon, Oct 31, 2016 0:00:02 AM
Run Code Online (Sandbox Code Playgroud)
(请注意,如果 shebang 是#!/bin/sh
,即使/bin/sh
是指向 bash 的链接,以下脚本片段也有效。但是,如果 shebang 是#!/bin/bash
,则需要添加一个shopt -s expand_aliases
命令以使别名在脚本中工作。)
所以,对于我的第一个技巧:
alias echo='{ set +x; } 2> /dev/null; builtin echo'
Run Code Online (Sandbox Code Playgroud)
现在,当我们说 时echo "Message"
,我们正在调用别名,它不会被跟踪。别名关闭跟踪选项,同时抑制来自set
命令的跟踪消息(使用在user5071535 的回答中首先介绍的技术),然后执行实际echo
命令。这让我们获得了类似于 user5071535 的答案的效果,而无需在每个 echo
命令中编辑代码。但是,这会导致跟踪模式关闭。我们不能将 aset?-x
放入别名中(或者至少不容易),因为别名只允许用字符串替换单词;别名字符串的任何部分都不能在参数之后注入命令中
(例如,"Message"
)。因此,例如,如果脚本包含
date
echo "The quick brown fox"
echo "jumps over the lazy dog."
date
Run Code Online (Sandbox Code Playgroud)
输出将是
+ date
Mon, Oct 31, 2016 0:00:03 AM
The quick brown fox
jumps over the lazy dog.
Mon, Oct 31, 2016 0:00:04 AM # Note that it doesn’t say + date
Run Code Online (Sandbox Code Playgroud)
所以你仍然需要在显示消息后重新打开跟踪选项 - 但在每个连续命令块之后只需要一次echo
:
date
echo "The quick brown fox"
echo "jumps over the lazy dog."
set -x
date
Run Code Online (Sandbox Code Playgroud)
如果我们能在 aset?-x
之后自动制作就好了echo
——而且我们可以,但需要更多技巧。但在我介绍之前,请考虑一下。OP 从使用#!/bin/sh?-ex
shebang 的脚本开始。隐式地,用户可以x
从 shebang 中删除并拥有一个正常工作的脚本,而无需执行跟踪。如果我们能够开发一种保留该属性的解决方案,那就太好了。这里的前几个答案不符合该属性,因为它们echo
无条件地在语句之后“返回”跟踪,而不管它是否已经打开。
这个答案显然没有认识到这个问题,因为它取代了 echo
带跟踪输出的输出;因此,如果关闭跟踪,所有消息都会消失。我现在将提出一个解决方案,该解决方案有条件地在echo
语句之后重新打开跟踪——仅当它已经打开时。将其降级为无条件“回溯”的解决方案是微不足道的,只能作为练习。
alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'
echo_and_restore() {
builtin echo "$*"
case "$save_flags" in
(*x*) set -x
esac
}
Run Code Online (Sandbox Code Playgroud)
$-
是选项列表;与设置的所有选项对应的字母的串联。例如,如果设置了e
和x
选项,$-
则将是包含e
和的一堆字母x
。我的新别名(上图)$-
在关闭跟踪之前保存了 的值。然后,在关闭跟踪的情况下,它将控制权交给 shell 函数。该函数执行实际操作echo
,然后检查x
在调用别名时是否打开了该选项。如果该选项打开,则该功能将其重新打开;如果它已关闭,则该功能将其关闭。
您可以shopt
在脚本的开头插入以上七行(八行,如果包含),其余部分不理会。
这会让你
#!/bin/sh -ex #!/bin/sh -e #!/bin/sh –x或者只是简单的
#!/bin/sh它应该按预期工作。
(shebang) 命令1 命令2 命令3 设置 -x 命令4 命令5 命令6 设置 +x 命令7 命令8 命令9和
echo
,在这种情况下它将被执行但不会被跟踪。(但即使命令 5 是echo
,命令 6 仍然会被跟踪。)echo
,命令 9 仍然不会被跟踪。x
.PS 我发现,在我的系统上,我可以builtin
在我的中间答案中省略关键字(那个只是 的别名echo
)。这并不奇怪;bash(1) 表示,在别名扩展期间,...
... 与被扩展的别名相同的单词不会再次扩展。这意味着一个可能的别名
ls
来ls?-F
,例如,和bash不会尝试递归扩展替换文本。
毫不奇怪,echo_and_restore
如果builtin
省略关键字1,则最后一个答案(带有 的答案)将失败。但是,奇怪的是,如果我删除builtin
并切换顺序,它会起作用:
echo_and_restore() {
echo "$*"
case "$save_flags" in
(*x*) set -x
esac
}
alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'
Run Code Online (Sandbox Code Playgroud)
__________
1 ?它似乎会引起未定义的行为。我见过
/dev/null: Bad address
错误消息,并且Chr*_*ian 15
我在InformIT找到了部分解决方案:
#!/bin/bash -ex
set +x;
echo "shell tracing is disabled here"; set -x;
echo "but is enabled here"
Run Code Online (Sandbox Code Playgroud)
产出
set +x;
shell tracing is disabled here
+ echo "but is enabled here"
but is enabled here
Run Code Online (Sandbox Code Playgroud)
不幸的是,这仍然是回声set +x
,但至少在那之后它很安静。所以它至少是问题的部分解决方案。
但也许有更好的方法来做到这一点?:)
小智 5
这种方式通过摆脱set +x
输出来改进您自己的解决方案:
#!/bin/bash -ex
{ set +x; } 2>/dev/null
echo "shell tracing is disabled here"; set -x;
echo "but is enabled here"
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
53553 次 |
最近记录: |