我的目标是通过 ssh 远程到服务器,启动屏幕,启动脚本,让脚本运行,然后退出 ssh 会话,同时保持屏幕运行自己的 python 脚本。这就是我所拥有的:
ssh -t myuser@hostname screen python somepath.py -s 'potato'
问题是,运行它后,我必须手动 ctrl + a + d,然后自己退出 ssh 会话。有没有一种方法可以一次性完成这一切,而不需要人工交互?
编辑:我已经尝试过使用 -dm 的建议方法
这是我正在测试的内容,以便更容易看到:
ssh -t user@host screen "top"
远程我看到这个:
user 2557 0.0 0.2 27192 1468 ? Ss 13:35 0:00 SCREEN top
user 2562 0.0 0.1 11740 932 pts/0 S+ 13:35 0:00 grep --color=auto SCREEN
但如果我这样做:
ssh -t user@host screen -dm "top"
我立即关闭了与主机的连接。我的 grep 中什么也没有
ps aux | grep SCREEN
user 2614 0.0 0.1 11740 932 pts/0 S+ 13:36 0:00 grep --color=auto SCREEN
答案1
您可以使用-d -m
屏幕会话来执行以下操作:
ssh myuser@hostname screen -d -m "python somepath.py -s 'potato'"
这将创建一个新的屏幕会话,在其中运行您的命令并自动将您与它分离。
该选项记录为
-d -m
以分离模式启动屏幕。这会创建一个新会话,但不会附加到它。这对于系统启动脚本很有用。
答案2
我发现该-d -m
选项有效,但不适用于引号。我需要这样做:
ssh myuser@hostname screen -d -m python somepath.py -s 'potato'
我不知道为什么接受的答案在命令周围有引号,因为 GNU 文档中没有要求它们,并且它们在我的系统(Centos 7)上破坏了它。
值得一提的是:我注意到在 Jenkins 下通过 ssh 运行时屏幕不会保持活动状态。当父级 ssh 连接和 sh 脚本运行时它是活动的,但当父级关闭时它就死掉了,所以可能存在 screen 无法解决问题的情况。
我什至尝试使用这个技巧:
添加
script /dev/null
在屏幕调用之前,但它没有解决问题。我不知道詹金斯在做什么魔法让一切都死掉,但它很有效。
它可能会被詹金斯进程杀手杀死,可以通过添加以下内容来禁用:
export BUILD_ID=dontKillMe
https://serverfault.com/questions/502593/starting-a-forever-process-in-a-jenkins-build-step
就我而言,我很幸运通过添加 dontKillMe 来保持长时间运行的进程(ssh 隧道)继续运行,尽管我不再使用 screen,因为它是不必要的。