【问题标题】:set -x and wildcard expansionset -x 和通配符扩展
【发布时间】: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

标签: bash shell wildcard


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 2012-07-12
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    相关资源
    最近更新 更多