Linux 尝试从sh`echo';使用bash时出现语法错误;rm-rf!(食谱)和猛击`

Linux 尝试从sh`echo';使用bash时出现语法错误;rm-rf!(食谱)和猛击`,linux,bash,shell,sh,packer,Linux,Bash,Shell,Sh,Packer,当我使用/bin/sh时,我可以通过bash发出命令,只需回显它 vagrant@vagrant:~$ sh $ echo 'ls' | bash some.sh 但是当我尝试使用这个命令时,rm-rf!(食谱)我明白了 $ echo 'rm -rf !(cookbooks)' | bash bash: line 1: syntax error near unexpected token `(' bash: line 1: `rm -rf !(cookbooks)' 我需要从/bin/sh发

当我使用/bin/sh时,我可以通过bash发出命令,只需回显它

vagrant@vagrant:~$ sh
$ echo 'ls' | bash
some.sh
但是当我尝试使用这个命令时,
rm-rf!(食谱)
我明白了

$ echo 'rm -rf !(cookbooks)' | bash
bash: line 1: syntax error near unexpected token `('
bash: line 1: `rm -rf !(cookbooks)'
我需要从/bin/sh发出这个命令

@来自包装商供应脚本的anubhava

if [ -d "/opt/chef/chef-solo/" ]; then
  cd /opt/chef/chef-solo
  rm -rf !(cookbooks)
fi
!(烹饪书)
是一个extglob。默认情况下不启用它们;您需要在bash的前一行中运行
shopt-s extglob
(因为解析器逐行操作)以使其有效

因此:

…或者您可以通过命令行启用extglobs(感谢提供的附录):

顺便说一句,可以在POSIX sh中执行此操作,而无需使用extglobs。例如:

# wrap in a function to have a separate $@ rather than overriding global
delete_all_but_cookbooks() {
  set --
  for f in *; do
    [ "$f" = "cookbooks" ] || set -- "$@" "$f"
  done
  rm -rf "$@"
}
delete_all_but_cookbooks
…或者更简单地说,只需使用“查找”:

find . -mindepth 1 -maxdepth 1 -name cookbooks -prune -o -exec rm -rf '{}' +
!(烹饪书)
是一个extglob。默认情况下不启用它们;您需要在bash的前一行中运行
shopt-s extglob
(因为解析器逐行操作)以使其有效

因此:

…或者您可以通过命令行启用extglobs(感谢提供的附录):

顺便说一句,可以在POSIX sh中执行此操作,而无需使用extglobs。例如:

# wrap in a function to have a separate $@ rather than overriding global
delete_all_but_cookbooks() {
  set --
  for f in *; do
    [ "$f" = "cookbooks" ] || set -- "$@" "$f"
  done
  rm -rf "$@"
}
delete_all_but_cookbooks
…或者更简单地说,只需使用“查找”:

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

你想在这里做什么?…事实上,我意识到(相当晚了)简单的解决方案就是使用find,而不是依赖bashism或POSIX sh扭曲。由于
--delete
选项是
find
的GNU扩展,使用它将类似于bashism。你想在这里做什么?…实际上,我意识到(很晚才意识到)简单的解决方案就是使用find,而根本不依赖bashisms或POSIX sh扭曲。由于
--delete
选项是
find
的GNU扩展,使用它可以与Bashim相媲美。当您使用
bash-oextglob
启动
bash
时,可以启用
extglob
。GNU find has--delete action builded inI将添加shopt-s extglob需要在当前上下文之前运行,而不仅仅是在当前行。我有一个案例,我对extglob的需求在“if”中,因此shopt-s extglob必须在“if”之外运行。将其放置在所需行上方是不够的(收到相同的错误“…意外标记”(“)。当您使用
bash-O extglob
启动
bash
时,您可以启用
extglob
。GNU find has--delete action build inI将添加shopt-s extglob需要在当前上下文之前运行,而不仅仅是在当前行。我有一个案例,我对extglob的需求在“if”中,因此shopt-s extglob必须在外部运行“if”。将其置于所需行上方是不够的(收到相同的错误“…意外标记”()。