【问题标题】:unexpected operator [: git: in bourne shell script 'if' conditional statement意外的运算符 [:git:在 bourne shell 脚本中的“if”条件语句
【发布时间】:2012-05-14 18:25:42
【问题描述】:

我通过大量videos 观看了出色的shell 脚本课程。既然我认为我对 Bourne shell 相当熟悉,我决定编写我的第一个 shell 脚本。

脚本目标:检查 git 工作目录是否干净。如果是这样,将工作目录覆盖到名为deployment 的分支。最后,将部署分支推送到源站。

我最终得到了这段代码:

#!/bin/sh

######################################################
# Deploys working directory to git deployment branch.
# Requires that the working directory is clean.
######################################################

#check if the working directory is clean
if [ git diff-index --quiet HEAD ]
then
    if [ git branch -f deployment ]
    then
        if [ git push origin deployment ]
        then
            echo
            echo "OK. Successfully deployed to git deployment branch."
            echo
            exit 0 #success
        else
            echo
            echo "Error: failed to push deployment branch to origin."
            echo
            exit 1 #failure
        fi
    else
        echo
        echo "Error: failed to create or overwrite deployment branch."
        echo
        exit 1 #failure
    fi
else
    echo
    git status #show the status of the working directory
    echo
    echo "Error: working directory is not clean. Commit your changes first..."
    echo
    exit 1 #failure
fi

不幸的是,这似乎给了我一个错误:./tools/deploygit: 9: [: git: unexpected operator

为什么会这样?我在if [ git diff-index --quiet HEAD ] 中使用了哪些意外的运算符?

作为奖励,您对如何提高此脚本的效率、逻辑或可读性有任何建议或技巧吗?

【问题讨论】:

  • 从逻辑上讲,如果你这样做会更容易理解: die() { echo "ERROR: $*" >&2; 1号出口; }; git diff-index --quiet HEAD ||工作目录不干净; git 分支 -f 部署 || die 未能创建或覆盖部署分支 ...
  • 顺便说一句——你在哪个平台上? /bin/sh 是 POSIX sh,而不是 Bourne,几乎在过去二十年内构建的所有操作系统上,Sun 都是唯一的落后者。 (Bash 的名字暗示 Bourne 是它的前任,但这是一个牺牲准确性以支持双关语的例子)。

标签: debugging bash shell unix sh


【解决方案1】:

在此声明中:

if [ git diff-index --quiet HEAD ]

[test 命令的别名,所以您实际运行的是...

if test git diff-index --quiet HEAD ]

...这不是你的意思。您不需要使用test 命令来评估命令的结果;你应该这样做:

if git diff-index --quiet HEAD

查看if 命令的文档:

$ help if
if: if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi

if 语句的条件参数是命令。通常,test 命令用于使其看起来像其他语言,但您可以将 any 命令放在那里。以 0 的返回码退出的事物评估为 true,而其他任何事物的评估结果为 false。

【讨论】:

  • 我不敢相信我错过了这个。视频很好地解释了[实际上是测试程序。非常感谢。
最近更新 更多