我经常以交互方式循环,例如我的文件,并希望对所有文件执行特定操作,假设我想重命名所有文件:
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
没有帮助,因为它不仅会显示命令,还会调用它,然后它可能已经太晚了。
答案 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
在脚本开头