我经常交互式循环例如我的文件,并希望对所有文件执行特定操作,假设我想重命名所有文件:
for file in $(ls); do mv "$file" "${file}_new"; done
Run Code Online (Sandbox Code Playgroud)
这很好用.但在调用此命令之前,我想看看它实际上做了什么,所以我会在前面添加一个回声
for file in $(ls); do echo mv "$file" "${file}_new"; done
Run Code Online (Sandbox Code Playgroud)
然后它会显示它将调用的所有命令.如果我对他们感到满意,我会删除echo并执行它.
但是,当命令更微妙时可能包括管道或多个命令时,这不再起作用.当然我可以使用,'所以特殊字符不会被解释,但后来我没有参数扩展.我也可以逃避特殊角色,但这会非常繁琐.
我的问题是,最好的方法是什么?我已经阅读了man bash关于该选项的选项-n,该选项执行"读取命令但不执行它们.这可用于检查shell脚本是否存在语法错误.交互式shell会忽略这一点." 这正是我需要的,但我需要它用于交互式shell.注意选项-x或者-v没有帮助,因为它不仅会显示命令,还会调用它,然后它可能已经太晚了.
dev*_*ull 27
这个线程会告诉你为什么显示命令而不是执行那些(也就是干运行)的选项永远不会实现bash.
请参阅Eric Blake的回复:
>我的问题是为什么不能提供这样的选择或提供,一点想法会说明为什么永远不会实现这一点.这样的选项会输出以下内容:
Run Code Online (Sandbox Code Playgroud)if complex_command; then foo=command1 else foo=command2 fi $foo args在线上
$foo args,没有办法知道$foo扩展到什么,除非你以前执行过(不仅仅是扫描)complex_command.因此,没有办法在不运行的情况下干掉最终结果,但是运行事情与干运行的目标背道而驰.也就是说,您可能对该
bashdb项目感兴趣,该项目使用bash钩子提供调试器接口,您可以单步执行bash脚本; 它与告诉你脚本会做什么不一样,但它至少可以让你控制脚本实际运行的程度.
Aar*_*lla 24
如devnull所解释的那样,"干运行"没有选项,但有一个简单的解决方法:
debug=
#debug=echo
$debug mv "$file" "${file}_new"
Run Code Online (Sandbox Code Playgroud)
如果从第二个分配中删除注释(不更改其他任何内容),则为危险mv命令启用"干运行" .
更复杂的方法是检查某些条件(如命令行选项):
debug=
if [[ ...enable dry run?... ]]; then
debug=echo
fi
Run Code Online (Sandbox Code Playgroud)
注意:只有在-u启用了选项("将未设置的变量视为替换时的错误.")时,才需要空赋值.
重要提示:当命令使用重定向时,这将无法正常工作(因为shell在命令启动之前始终会执行这些操作).
有一个名为maybe 的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]
Run Code Online (Sandbox Code Playgroud)
实际上你可以在脚本中做到这一点
添加:
set -x # Print commands and their arguments as they are executed.
set -n # Read commands but do not execute them
Run Code Online (Sandbox Code Playgroud)
在脚本的开头
另外一个好的做法是添加set -e错误退出
(更多参考man集)
| 归档时间: |
|
| 查看次数: |
27146 次 |
| 最近记录: |