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

ele*_*128 1 mac-osx path jenkins

我有一个在 macOS 上运行的 Jenkins slave 通过ssh slave, then 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
Run Code Online (Sandbox Code Playgroud)

这很好用,echo $PATH在 Jenkins 工作中与echo $PATH在通过 ssh 打开的终端会话中运行相同。

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

echo $PATHJenkins slave 的两次都简单地等于: /usr/bin:/bin:/usr/sbin:/sbin 因此 PATH 没有从当前登录的用户正确设置。

  • 该进程在用户帐户下运行
  • 甚至 Jenkins slave 的进程都在用户账户下运行
  • 我们仅~/.profile用于设置环境变量...

怎么了?当我通过 launchctl 或 Application 启动上述脚本时,为什么 Jenkins slave 没有正确设置 PATH 变量?

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

Jes*_*man 6

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

#!/bin/bash -l
Run Code Online (Sandbox Code Playgroud)

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

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