2014-02-05 19 views
0

当我使用/ bin/sh的我可以简单地通过回它通过发出命令庆典语法错误,当我尝试使用bash从sh`echo'rm -rf!(cookbooks)'| bash`

[email protected]:~$ sh 
$ echo 'ls' | bash 
some.sh 

但是当我尝试使用此命令rm -rf !(cookbooks)我得到这个

$ echo 'rm -rf !(cookbooks)' | bash 
bash: line 1: syntax error near unexpected token `(' 
bash: line 1: `rm -rf !(cookbooks)' 

我需要从/ bin/sh发出这个命令。从封隔器http://www.packer.io/提供脚本

if [ -d "/opt/chef/chef-solo/" ]; then 
    cd /opt/chef/chef-solo 
    rm -rf !(cookbooks) 
fi 
+0

什么是你想在这里做什么? – anubhava

+0

...实际上,我意识到(相当迟到)简单的解决方案就是使用find,而不是依赖bashisms *或* POSIX sh扭曲。 –

+0

由于'--delete'选项是对'find'的GNU扩展,所以使用它将会与bashism相媲美。 – chepner

回答

6

!(cookbooks)

@anubhava是extglob。它们并未默认启用;您需要在前一行bash中运行shopt -s extglob(因为解析器逐行运行)才能使其生效。

所以:

printf '%s\n' 'shopt -s extglob' 'rm -rf !(cookbooks)' | bash 

...或者你可以启用通过命令行extglobs(感谢chepner的附录):

echo 'rm -rf !(cookbooks)' | bash -O extglob 

顺便说一句,这是可能在POSIX sh中执行此操作,而不使用extglobs。例如:

# wrap in a function to have a separate [email protected] rather than overriding global 
delete_all_but_cookbooks() { 
    set -- 
    for f in *; do 
    [ "$f" = "cookbooks" ] || set -- "[email protected]" "$f" 
    done 
    rm -rf "[email protected]" 
} 
delete_all_but_cookbooks 

...或者,更简单,只需使用find:

find . -mindepth 1 -maxdepth 1 -name cookbooks -prune -o -exec rm -rf '{}' + 
+2

当你用'bash -O extglob'启动'bash'时,你可以启用'extglob'。 – chepner

+0

@chepner,谢谢 - 编辑它在。 –

+0

和GNU发现有--delete动作内置 – Basilevs