显示命令而不执行它们

时间:2013-10-01 11:36:44

标签: bash

我经常以交互方式循环,例如我的文件,并希望对所有文件执行特定操作,假设我想重命名所有文件:

for file in $(ls); do mv "$file" "${file}_new"; done

这很好用。但在调用此命令之前,我想看看它实际上做了什么,所以我会在前面添加一个回声

for file in $(ls); do echo mv "$file" "${file}_new"; done
然后它会显示它将调用的所有命令。如果我对他们感到满意,我会删除echo并执行它。

然而,当命令更加微妙时,可能包括管道或多个命令,这不再起作用。当然我可以使用'因此特殊字符不会被解释,但是我没有参数扩展。我也可以逃避特殊角色,但这会非常繁琐。

我的问题是,最好的方法是什么?我在man bash中读到了关于选项-n的问题,它执行“读取命令但不执行它们。这可能用于检查shell脚本是否存在语法错误。交互式shell会忽略它。 “这正是我需要的,但我需要它用于交互式shell。请注意,选项-x-v没有帮助,因为它不仅会显示命令,还会调用它,然后它可能已经太晚了。

4 个答案:

答案 0 :(得分:25)

This线程会告诉您为什么显示命令而不执行命令的选项(a.k.a 干运行)永远不会为bash实现。

请参阅Eric Blake的回复:

  

>我的问题是为什么不能提供这样的选项,或者

     

一点想法会说明为什么永远不会实施。什么   将这样的选项输出为以下内容:

if complex_command; then
  foo=command1
else
  foo=command2
fi
$foo args
     

$foo args的行上,无法知道$foo展开的内容   除非你以前执行过(不仅仅是扫描过)   complex_command。因此,最后没有办法干运行   结果将是没有运行的东西,但运行的东西是反制的   为了干跑的目标。

     

那就是说,您可能对使用的bashdb项目感兴趣   bash钩子提供一个调试器接口,你可以单步执行   通过bash脚本;这和告诉你是什么不一样   脚本会这样做,但它至少可以让你控制多少   该脚本实际上已经运行。

答案 1 :(得分:22)

explained by devnull没有“干跑”选项,但有一个简单的解决方法:

debug=
#debug=echo

$debug mv "$file" "${file}_new"

如果从第二个作业中删除评论(不更改其他任何内容),则为危险的mv命令启用“干运行”。

更精细的方法是检查某些条件(如命令行选项):

debug=
if [[ ...enable dry run?... ]]; then
    debug=echo
fi

注意:仅当您启用了选项-u(“将取消设置时将错误设置为错误。”)时,才需要空分配。

重要事项:当您的命令使用重定向时,这将无法正常工作(因为在命令启动之前shell始终会执行这些操作)。

答案 2 :(得分:9)

有一个名为“github”的软件包,可能就是这里的一个例子:

$ maybe rm file
> maybe has prevented rm file from performing 1 file system operations:
>
> delete /home/user/file
>
> Do you want to rerun rm file and permit these operations? [y/N]

答案 3 :(得分:1)

实际上您可以在脚本中完成

添加:

set -x 
set -n

在脚本开头