我有一个作为服务运行的应用程序。此应用程序绑定到 TCP 端口。
我想运行更新(sh 脚本),我想独立于应用程序服务运行(以便能够执行例如从脚本重新启动服务)。
我终于能够使用 systemd-run 范围来做到这一点,但我发现,分离的范围保持原始绑定的 TCP 端口被占用(即使它不使用它做任何事情),所以当我重新启动应用程序服务时,它是无法再次绑定。
我尝试运行更新脚本:
systemd-run --scope --unit=appupgrade nohup $script_path -d & disown
有没有办法让systemd作用域不占用服务始发港?
使用
--scope
模式,进程实际上根本不分离:它直接作为子进程启动,因此继承所有文件描述符(包括 TCP 套接字)。
一种解决方案是将套接字标记为不可继承(
SOCK_CLOEXEC
又名 close-on-exec),或者在执行 systemd-run 之前显式关闭它(我相信 posix_spawn 有一个关闭 FD 的选项?)。
但是,如果您确实希望分离进程,那么 不要使用
--scope
。使用默认的“服务”模式并让 systemd 生成进程 - 那么您将不需要 nohup
,您将不需要 & disown
,当然该进程将不再继承不需要的文件描述符。