Bash set-x和通配符扩展

Bash set-x和通配符扩展,bash,shell,wildcard,Bash,Shell,Wildcard,在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 f

在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个文件没问题,但10000个文件没那么好

所需的输出是

rm *.foo
我的第一个想法是在引号中加上*.foo

rm "*.foo"
然而,这就产生了错误

rm: cannot remove ‘*.foo’: No such file or directory

是否有一种方法可以使用set-x在不扩展通配符的情况下回显命令?

对于许多情况,简单的“-x”或“-v”不起作用(根据上面的注释),并且保持在您的编码标准内(没有单独的回显),请考虑:

VAR=/tmp/123
$SHELL -cv "ls $VAR/*"

它将执行命令,但将使用变量替换、命令替换记录命令,但不使用通配符替换。

No
set-x
是一种调试工具,而不是日志记录工具。我会问执行该策略的人他们希望看到什么作为解决方法。请注意,这是一种比
echo rm*.foo
更好的做法(因为
echo
会丢弃有关参数边界位置的信息)。顺便说一句,在单个
rm
命令行上传递10000个文件根本不能保证有效(因为它可能超过操作系统的命令行长度限制)。有一个时刻,你会想,比如说,
find.-name'*.foo'-delete
只是出于性能原因——因此,
set-x
输出变得不合理应该被视为一个信号,即代码应该被修复,而不是作为需要解决的问题来读取。:)(请注意,
set-v
可能被认为是一种不运行扩展的替代方案;但是,正是出于这个原因,它不适合于
set-x
所服务的许多目的,因此,如果没有得到相关策略编写人员的支持,我不会进行这种转换;有时,人们无法跟踪到错误f如果您当前目录中有一个名为
-.foo
的文件,它将破坏您的代码,除非您将其更改为
rm-*.foo
,因为它将尝试设置
-.
-f
-o
标志)。如果您想更深入地描述为什么
echo
很糟糕,并且任何人都不应该将其与动态或未知参数一起使用,请参阅上的优秀答案,或者参阅POSIX规范中
echo
at的应用程序用法和基本原理部分;
echo
规范本身adv请改用
printf