【发布时间】:2019-09-18 17:59:53
【问题描述】:
在 shell 脚本中,我们的公司编码标准要求使用...
set -x
command
set +x
...用于记录,而不是...
echo "doing command"
command
但是,当通配符是命令的一部分时,这会产生非常冗长的输出。
例如...
for i in {1..10}; do touch $i.foo; done; # create 10 foo files
set -x # log command execution (stdout to be redirected to log file)
rm *.foo # delete foo files
set +x # end logging
...产生输出...
rm 10.foo 1.foo 2.foo 3.foo 4.foo 5.foo 6.foo 7.foo 8.foo 9.foo
对于 10 个文件还可以,但对于 10,000 个文件来说不是很好。
想要的输出是……
rm *.foo
我的第一个想法是把 *.foo 放在引号中......
rm "*.foo"
但是,这给出了错误...
rm: cannot remove ‘*.foo’: No such file or directory
有没有办法使用 set -x 来回显命令而不扩展通配符?
【问题讨论】:
-
否;
set -x是调试工具,而不是日志记录工具。我会询问执行该政策的人,他们希望看到什么作为解决方法。 -
请注意,这是比
echo rm *.foo更好的做法(因为echo会丢弃有关参数边界所在位置的信息)。 -
顺便说一句,在单个
rm命令行上传递 10,000 个文件根本不能保证工作(因为它可能会超过操作系统的命令行长度限制)。有一点你想,比如说,find . -name '*.foo' -delete只是出于性能原因——所以也许set -x输出变得不合理应该被视为代码应该被修复的信号,而不是被读为可以解决的问题. :) -
(请注意,
set -v可能被视为不运行扩展的替代方案;但是,正因为如此,它不适合set -x服务的许多目的,所以如果没有得到相关政策编写者的祝福,我不会进行这种转换;有时,如果不查看 确切*.foo扩展的字符串,就无法从日志中找到错误to; f/e,如果您在当前目录中有一个名为-.foo的文件,除非您将其更改为rm -- *.foo,否则它将破坏您的代码,因为它会尝试设置-.、-f和 @ 987654343@ 标志)。 -
如果您想更深入地描述为什么
echo很糟糕,并且任何人都不应该将其与动态或未知参数一起使用,请参阅unix.stackexchange.com/a/65819/3113 的优秀答案 - 或更短的阅读,请参阅echopubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html 的 POSIX 规范的应用程序使用和基本原理部分;echo规范本身建议改用printf!