【问题标题】:Why same command fails in GitLab CI?为什么相同的命令在 GitLab CI 中失败?
【发布时间】:2021-02-20 00:13:45
【问题描述】:

以下命令在终端上完美运行,但相同的命令在 GitLab CI 中失败。

echo Hello >> foo.txt; cat foo.txt | grep "test"; [[ $? -eq 0 ]] && echo fail || echo success

返回是success 但 GitLab CI 中的命令相同

$ echo Hello >> foo.txt; cat foo.txt | grep "test"; [[ $? -eq 0 ]] && echo fail || echo success
Cleaning up file based variables
ERROR: Job failed: command terminated with exit code 1

只是失败了。我不知道为什么。 echo $SHELL 在两者中都返回 /bin/bash

【问题讨论】:

  • 你在 GitLab 工作中使用的是哪个 shell?
  • @GlenThomas /bin/bash

标签: bash shell gitlab-ci gitlab-ci-runner


【解决方案1】:

问题来源

鉴于 CI 上下文中的“隐含”set -e,您观察到的行为非常标准。

更准确地说,您的代码包含三个复合命令:

echo Hello >> foo.txt
cat foo.txt | grep "test"
[[ $? -eq 0 ]] && echo fail || echo success 

并且grep "test" 命令返回一个非零退出代码(即1)。结果,脚本立即退出,最后一行没有执行。

请注意,此功能在 CI 上下文中很典型,因为如果某个中间命令在复杂脚本中失败,我们通常希望失败,并避免运行下一个命令(这可能是“离题" 给出错误)。

你也可以在本地复制它,例如:

bash -e -c "
echo Hello >> foo.txt
cat foo.txt | grep "test"
[[ $? -eq 0 ]] && echo fail || echo success 
"

大致相当于:

bash -c "
set -e
echo Hello >> foo.txt
cat foo.txt | grep "test"
[[ $? -eq 0 ]] && echo fail || echo success 
"

相关手册页

更多见解:

如何解决这个问题?

您应该采用另一种措辞,避免 [[ $? -eq 0 ]] a-posteriori 测试。因此,可能返回非零退出代码而不意味着失败的命令应该受到某些if 的“保护”:

echo Hello >> foo.txt
if cat foo.txt | grep "test"; then
  echo fail
  false  # if ever you want to "trigger a failure manually" at some point.
else
  echo success
fi

另外,请注意 grep "test" foo.txt 会比 cat foo.txt | grep "test" 更惯用 - 这正是 UUOC 的一个实例(无用的 cat)。

【讨论】:

  • 在您写之前我只是在阅读 cat 的无用用法:D 感谢您的详细解释
【解决方案2】:

我不知道为什么。

Gitlab 一次执行一个命令并检查每个命令的退出状态。当退出状态不为零时,作业失败。

foo.txt 中没有test 字符串,因此命令cat foo.txt | grep "test" 以非零退出状态退出。因此作业失败了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 2020-09-09
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 2019-04-07
    相关资源
    最近更新 更多