为什么通过 launchctl 启动 Jenkins 从属时 PATH 不同?

为什么通过 launchctl 启动 Jenkins 从属时 PATH 不同?

我有一个在 macOS 上运行的 Jenkins 从属程序ssh slave,然后screen通过启动以下脚本,确保在服务器发生故障时重新连接:

#!/usr/bin/env bash

function startSlave() {
  java -jar /Users/user/slave.jar -jnlpUrl https://jenkins.company.com/computer/slave-office/slave-agent.jnlp -secret xyz
  sleep 3
}

startSlave

while true; do
  PID=$(pgrep "slave-agent.jnlp" | awk '{print $2}')
  if [[ -z $PID ]]; then
    echo "Jenkins slave has died, restarting..."
    startSlave
  fi
  sleep 60
done

这非常有效,在 Jenkins 作业中,它与通过 ssh 打开的终端会话中echo $PATH运行相同。echo $PATH

但有时我们需要重启机器,所以我希望这个脚本在登录时执行。我测试了通过 launchctl solution 和 macOS 用户启动应用程序列表中的应用程序启动脚本。

echo $PATHJenkins 从属的 两个时间都简单相等:/usr/bin:/bin:/usr/sbin:/sbin 因此,当前登录的用户未正确设置 PATH。

  • 该进程正在用户账户下运行
  • 即使 Jenkins 从属进程也在用户帐户下运行
  • 我们仅用于~/.profile设置环境变量...

出了什么问题?当我通过 launchctl 或应用程序启动上述脚本时,为什么 Jenkins 从属服务器无法正确设置 PATH 变量?

更新:我通过在 Jenkins 作业中明确获取配置文件来使其工作: source /Users/leanplumbuild/.profile 有人知道为什么 Jenkins-Slave 没有自动执行此操作吗?

答案1

我不确定,但我的第一个猜测是,这是因为 Jenkins 没有将子 shell 作为“登录 shell”启动。当您在交互式环境中登录 shell 时,shell 加载环境文件的方式与通过“非交互式”环境(如 cron)启动时不同。要更改此行为,并使您的环境“匹配”得更准确,您需要将子 shell 作为登录 shell 启动。有多种方法可以做到这一点,我相信 Jenkins 有一种更强大的方法,但至少您可以尝试将第一个 sh-bang 行更改为:

#!/bin/bash -l

从工作中删除该明确的采购行。现在,看看一切是否正常!:)

作为参考,请查看 bash 手册页“INVOCATION”的长而复杂的部分。https://linux.die.net/man/1/bash

相关内容