"git-worktree-remove"命令失败时是否返回非零值



我正在编写一个bash脚本,在中,我想根据命令-git worktree remove的返回值来决定是执行command A还是执行command B

比方说,如果工作树被成功删除,那么我将执行command A。如果命令中提到的工作树名称是错误的,或者由于任何其他原因,如果git worktree remove失败,那么我想执行command B

因此,我提出了如下逻辑-

.
.
.
wt_del=$(git worktree remove -f $DIR)
echo $wt_del                                   ---> for debugging script
if [ $wt_del -eq 0]
then
git branch
read -p "Enter the branch : " BUG
git branch -d $BUG
else
echo "Failed to remove worktree $DIR"
.
.
.

当我使用无效的工作树名称运行此脚本时,我会看到类似于-wt_del =的输出所以这意味着git worktree remove命令没有返回任何表示成功或失败的整数值。那么我该如何做决定呢?

您应该在运行流程后立即检查退出代码。检查变量$?。如果不是0,则表示存在错误。

git blahblah
if [ $? -ne 0 ]; then
echo there was a problem
fi

这是一个通用的shell编程问题(根本不是Git特有的,在许多POSIX风格的shell中都是通用的,包括sh、bash、zsh等)。运行命令的语法很简单:

cmd arg1 arg2 ... argN

该命令的输出将转到标准输出。将命令封装在以美元符号为前缀的圆括号中,并将其分配给具有以下内容的变量:

var=$(cmd arg1 arg2 ... argN)

告诉shell捕获输出(通过将命令的标准输出重定向到某个位置,然后读取该输出)。命令的标准错误流不受影响,但使用:

var=$(cmd ... 2>&1)

将导致带括号的子命令将其自己的标准错误输出发送到其自己的标准输出已经所在的位置,也就是说,正在收集它的外壳。因此,如果您有一个同时打印到stdout和stderr的命令,则可以收集这两个输出。

这不是您想要做的。您想要保存命令的退出状态。要做到这一点,正如eftshift0所指出的,您需要使用$?伪变量:

cmd arg1 arg2 ... argN
status=$?

在一个普通的shell变量中捕获了退出状态后,您现在可以重复测试它,或者——如果您的shell支持算术——对状态进行算术运算,或者任何您喜欢的操作。

不过,正如phd在评论中所指出的,如果你只想检查一次状态,对于零与非零,那么方法是使用shell的if ...; then ...; else ...; fi构造:

if cmd arg1 arg2 ... argN
then
# stuff to do if the exit status was zero
else
# stuff to do if the exit status was nonzero
fi

请注意,then关键字必须出现在通常可以找到命令的位置:这就是为什么它位于单独的行上。您可以在if构造中使用整个管道,但只有最后一个命令的退出状态很重要:1

if cmd1 | cmd2 | cmd3; then
echo cmd3 exited zero
else
echo cmd3 exited nonzero
fi

这里then在同一行,但我们使用分号来确保它出现在独立命令的位置。分号终止三个命令管道。

自从你写了:

wt_del=$(git worktree remove -f $DIR)

您在这里捕获了git worktree remove标准输出,这并不是很有用。然后你有:

if [ $wt_del -eq 0]

它有一个语法故障:CCD_ 16应该通过空白空间与零分离。[程序要求其最后一个参数为]。bash中内置的变体因此抱怨道:

bash$ [ $wt_del -eq 0]
bash: [: missing `]'

这表明你在将实际脚本转换为发布目的时重新键入了它,因为你没有提到任何此类投诉。这是得到无用答案的良方。请注意,由于$wt_del可能是空的,因此应该引用它:修复以上内容会产生:

bash$ [ $wt_del -eq 0 ]
bash: [: -eq: unary operator expected
```none
Fixing *that* in turn produces the "correct" error:
```none
bash$ [ "$wt_del" -eq 0 ]
bash: [: : integer expression expected

但一般来说,这里需要CCD_ 20构造。大多数Git命令都试图产生一个有用的退出状态(这最终让我们回到git),但这些细节有时没有记录下来,所以你必须测试,然后希望你的版本得到的结果对所有版本都是通用的。

如果Git调用管道命令,那么它是用于脚本的,并且应该有一种完全可靠的方式从脚本中使用,包括可预测的、机器解析就绪的输出和可预测的有用的退出状态。不幸的是,git worktree不是一个管道命令,但它的list子命令有一个--porcelain选项;CCD_ 25表示它正被用于";管道模式";。因此,它应该具有可靠的退出状态。


1Bash有一个设置(pipefail)来调整这种行为。使用它们可能很强大,但会降低shell脚本的可移植性。Bash的PIPESTATUS数组提供了最多的控制,但使用起来很烦人。

在最初的Bourne shell中,最后一个命令状态重要技巧是通过让if ... then构造在子shell中运行整个...部分来安排的。如果子shell只有一个命令要运行,那么它将使用execve系统调用来运行它。如果它有一个管道,它将生成一个子shell来运行管道的每个附加部分,然后使用execve系统调用直接运行最后一个命令。这意味着管道中的最后一个命令是早期命令的进程!一些写得不好的命令有时会因此而出错。Bash仍然可以通过lastpipe设置来执行此操作。

相关内容

  • 没有找到相关文章

最新更新