当带有扩展通配选项的“cp”语句移动到“if”块时出现语法错误

par*_*y72 11 bash wildcards

在 Bash 中进行复制时遇到一些问题。这工作正常:

# Enable extended globbing and include filenames beginning with a '.'
shopt -s extglob dotglob
# Copy git repo to expected place
cp -r !($YOCTO_DIR) $POKY_DIR/$GIT_REPO_NAME/
Run Code Online (Sandbox Code Playgroud)

但当我if对此发表声明时:

if [ -z "$FROM_JENKINS" ]; then
    # FROM_JENKINS is blank, this is a local build

    # Enable extended globbing and include filenames beginning with a '.'
    shopt -s extglob dotglob
    # Copy git repo to expected place
    cp -r !($YOCTO_DIR) $POKY_DIR/$GIT_REPO_NAME/
fi
Run Code Online (Sandbox Code Playgroud)

我得到:

./build.sh: line 80: syntax error near unexpected token `('
Run Code Online (Sandbox Code Playgroud)

80 号线是cp. 如果我删除括号它会起作用:

./build.sh: line 80: syntax error near unexpected token `('
Run Code Online (Sandbox Code Playgroud)

为什么该if语句不喜欢括号中的cp

Hau*_*ing 19

问题在于读取和执行的顺序和“范围”。

整个if块只是一个命令。因此 shell 必须先读取该命令,然后才能执行该命令。

这意味着, WITHOUT 的 规则shopt -s extglob dotglob(我指的是这里的行,不是它的全部内容;正如 ilkkachu 在评论中指出的那样: thedotglob与问题无关)在if块结束之前都有效,因为 theshopt之后执行仅有的。如果没有的话,shopt -s extglob!(是非法的。

因此,您必须将 移至shopt之前if(并且可能会在else分支中将其恢复)。

  • 我认为这主要是关于“extglob”,因为它改变了 shell 语法的解析方式。即使在块内设置,“dotglob”也会生效。`shopt -u dotglob; 如果属实; 然后shopt -s dotglob;回声*b*;fi` 找到文件 `.bbb` (2认同)
  • 更好的是,选择“一组”选项并将它们全部“购买”到脚本的顶部。不要在玩游戏时到处打开和关闭“extglob”。它只会使脚本变得更长、更难阅读。 (2认同)