我有一个在 bash 脚本中工作的 grep 命令:
if grep 'stackoverflow' outFile.txt; then
exit 1
fi
在我的主机上运行时效果很好。但是,当我从 Jenkins 构建步骤调用它时,它每次都退出 0,没有看到“stackoverflow”。出了什么问题?
将以下行添加为“执行 Shell”命令的第一行
#!/bin/sh
grep 命令在找不到匹配项时以非零代码退出,这会导致 jenkins 将作业标记为失败。见下文。
在“执行Shell”的帮助部分
运行用于构建项目的 shell 脚本(默认为 sh,但这是可配置的)。该脚本将以工作区作为当前目录运行。输入你的 shell 脚本的内容。如果您的 shell 脚本没有像 #!/bin/sh 这样的标题行,那么将使用系统范围内配置的 shell,但您也可以使用标题行以另一种语言编写脚本(例如 #!/bin/perl ) 或控制 shell 使用的选项。
默认情况下,将使用“-ex”选项调用 shell。因此,所有命令在执行之前都会打印出来,如果任何命令以非零退出代码退出,则认为构建失败。同样,添加 #!/bin/... 行以更改此行为。
作为最佳实践,尽量不要在此处放置长的 shell 脚本。相反,考虑在 SCM 中添加 shell 脚本,然后简单地从 Jenkins 调用该 shell 脚本(通过 bash -ex myscript.sh 或类似的东西),以便您可以跟踪 shell 脚本中的更改。
我对这个问题的答案有点困惑!即对不起,但这里的答案对于这个问题是不正确的。这个问题很好/有趣,因为如果 grep 不成功(这可能是意外的),脚本中的普通 grep 确实会导致脚本失败退出,而 if 中的 grep 不会导致失败退出。
对于问题 exit 1 中显示的示例,如果 grep 命令成功运行(文件存在)并且如果在文件中找到字符串,则将完成。(grep 命令返回 0 退出代码到 if)。
@Gonen 添加 'ls -l outFile.txt' 的评论应该被跟进,看看失败的真正原因是什么。
TLDR;if 在 if 子句中捕获命令的退出代码:
在 jenkins 的 if 语句中“失败”(不匹配或错误)的 grep 命令不会导致 jenkins 脚本停止。而不是在 if 内失败的 grep 命令将导致 jenkins 停止并退出失败。
shell 中 if 语句中的命令的退出/返回代码处理是不同的。if 捕获返回代码,无论命令是成功还是失败,if 都会将成功返回到 $0(在 if 之后)(并在 if 或 else 中执行操作)。
来自 man bash:
如果列表;然后列出;[ elif 列表;然后列出;] ... [ 其他列表;] fi 执行 if 列表。如果其退出状态为零,则执行 then 列表。否则,依次执行每个elif列表,如果其退出状态为零,则执行对应的then列表,命令完成。否则,执行 else 列表(如果存在)。退出状态是最后执行的命令的退出状态,如果没有条件测试为 true 则为零。
为了说明,试试这个(在 bash 或 sh 中的结果相同):
$ if grep foo bar ; then echo got it; fi; echo $?
grep: bar: No such file or directory
0
$ touch bar
$ if grep foo bar ; then echo got it; fi; echo $?
0
$ echo foo >bar
$ if grep foo bar ; then echo got it; fi; echo $?
foo
got it
0
$ if grep foo bar ; then echo gotit; grep gah mah; fi; echo $?
foo
gotit
grep: mah: No such file or directory
2
我认为你的脚本有错误。您必须在“if”块的末尾添加“fi”:
if grep 'stackoverflow' outFile.txt; then
exit 1
fi
如果两者完全相同,它应该可以工作。您当前的目录或用户在两种环境中是否不同?您可能无法读取该文件。