2013-10-01 93 views
22

我经常交互式地遍历例如我的文件,并希望对他们进行具体操作,假设我想重命名所有文件:显示命令而不执行它们

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不起作用,因为它不仅会显示命令,还会调用它,然后它可能已经太晚了。

+1

从技术上讲,是没有办法来实现这一目标。 – devnull

+0

或者,您可以将别名每个命令清空为别名 ='bash -c“”'',以便接受参数,但不会执行任何操作。你可以运行一个* alias-emptifier *循环,执行你想要的进程,然后运行* alias-restore *命令 - 恢复它们的功能。 – Rubens

+2

顺便说一句,在$(ls)中使用'for file是为了没有理由牺牲一个子进程。为什么不使用''in file in *'? – cdarke

回答

21

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脚本;这跟告诉你脚本会做什么不一样,但它至少可以让你控制该脚本实际运行的多少或多少 。

16

有作为explained by devnull没有选项的“预演”,但有一个简单的解决方法:

debug= 
#debug=echo 

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

如果您从第二次分配的注释(不改变任何东西),启用了“干运行“为危险mv命令。

一个更复杂的方法是检查一些条件(如命令行选项):

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

注:空任务只有在必要的时候,你可以选择-u(“对待尚未设定的变量作为代替时出错。“)启用。

+0

无论设置是什么,都必须分配什么才能将调试恢复到initiall设置? PS:出于某种原因,似乎调试不可用在我的bash中 –

+1

@GeorgeVasiliou'debug'只是一个局部变量,我可以不指定任何东西或只输出其参数('echo')的命令。要恢复效果,只需简单地指定一下:'debug ='。 –

+0

如果您使用重定向,这将不起作用。 –

6

有一个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] 
相关问题