为什么 sh 踩在 Jenkins 管道中的第二个节点失败?

Why does sh step on second node in Jenkins pipeline fail?

尝试在第二个 node() 上执行 sh 步骤失败。 最小示例:

node('windows') {
    env.PATH = "C:\some\path;${env.PATH}"
    // ...
}

node('linux') {
    sh "echo 'Hello World!'" // this fails
}

错误信息是:

nohup: failed to run command 'sh': No such file or directory

PATH 环境变量已正确设置为在两个节点上都包含 sh 命令。

为什么第二个节点上的sh步骤会失败?

tl;dr: 问题是用赋值设置 env.PATH。使用 withEnv() 代替:

node('windows') {
    withEnv('PATH+some=C:\some\path') {
        // ...
    }
}

node('linux') {
    sh "echo 'Hello World!'"
}

解释:

pipeline tutorial后面的一节中,据说

environment variable overrides are limited to being global to a pipeline run

这意味着当像这样 env.PATH = ... 设置环境变量时,此变量 固定用于管道脚本的其余部分 因此将 覆盖该环境变量在所有后续节点上的实际值。因此它反转了 env 属性设置为节点环境变量的实际值的正常行为。

所以我们的 Linux 节点以 Windows 节点的 PATH 变量结束。 这就是找不到 sh 的原因。
好奇的注意事项: nohup 仍然被发现,因为它是由 Jenkins 客户端直接执行的,该客户端使用节点的“真实”环境变量。但是詹金斯随后为 nohup 进程设置了修改后的环境,这就是为什么 nohupPATH.

中找不到 sh 的原因