Launchd在OSX上无法使用bash与teamcity代理运行

6
我有一个名为 startup.sh 的 shell 脚本,它执行以下操作(创建 RAM 磁盘并启动 TeamCity 代理程序):
#!/bin/bash

DISK=`/usr/bin/hdiutil attach -nobrowse -nomount ram://16777216`

/usr/sbin/diskutil erasevolume HFS+ "RamDiskCache" $DISK

/Users/administrator/buildAgent/bin/agent.sh start

我可以通过在命令行输入./startup.sh来运行它,它能够正确地执行。但当我从launchd运行时,它只会创建内存磁盘,而Teamcity无法启动。

我的launchd plist位于~/Library/LaunchAgents目录中。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.datafinch.teamcity</string>
        <key>Program</key>
        <string>/Users/administrator/startup.sh</string>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>

我错过了什么?

编辑

这是agent.sh文件:

https://gist.github.com/chriskooken/19f5856e3ce3c2322c53cb0afa69b057


@andlrc 抱歉,那只是我最后的尝试。我已经更新了问题。 - Chris Kooken
/Users/administrator/buildAgent/bin/agent.sh 包含什么内容? - Mark Setchell
@MarkSetchell,我在问题中添加了该文件的gist。 - Chris Kooken
我怀疑问题几乎肯定是你的脚本中没有指定 PATH,而在 launchd 下环境与交互式 shell 运行时不同。 - Mark Setchell
尝试在您的shell中运行env > /tmp/a,并在startup.sh中运行env > /tmp/b,然后运行opendiff /tmp/{a,b} - Mark Setchell
1个回答

3
您的agent.sh脚本在后台启动了TeamCity代理,然后退出。这与使用launchd管理作业的方式相反--launchd期望其作业在前台运行,这样它可以监视它们,在它们崩溃时重新启动它们,在适当时关闭它们等等。基本上,您正在使用PID文件处理的所有内容,都是launchd通常为您处理的。在这种情况下,直接的问题是,当launchd中的一个作业退出(在它在后台运行TeamCity之后几乎立即退出)时,launchd将清理任何残留下来的混乱,包括杀死任何孤立的子进程,比如说TeamCity代理。
您有两个选择:
- 转换为使用launchd的方式。这意味着用检查先决条件、查找Java等操作替换agent.sh脚本,然后在前景中运行TeamCity代理。实际上,最好使用“exec”来运行代理,这样代理就直接作为launchd的子进程而不是shell(作为launchd的子进程)的子进程运行;这使得launchd可以更直接地连接并监视它。 - 通过在.plist中添加<key>AbandonProcessGroup</key><true/>来告诉launchd不要杀死被遗弃的子进程。这更简单,但是您将放弃所有其他的launchd管理功能。

这个完美地运行了。我现在使用了AbandonProcessGroup。谢谢! - Chris Kooken

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接