通过ssh获取nohup进程的PID

3
我希望能够通过ssh获取我启动的进程的PID。
我有一个bash脚本,以下是我的代码:
SSH_COMMAND='ssh'
cmd=`eval $my_cmd`
PROG_CMD="$program $cmd"
$SSH_COMMAND root@server "(nohup $PROG_CMD) & echo "'$!'" > prog.pid"

请注意,变量“program”和“my_cmd”在JSON文件中定义(分别包含我的程序和启动程序的命令)。
我的程序在服务器上以预期方式启动,但是我在“prog.pid”文件中没有正确的PID(即:程序的PID)。
编辑:我执行了SSH_COMMAND的echo并获得了以下输出:
 ssh root@server (my_program args > output.log 2>&1 & ) & echo $! > prog.pid

args:我的程序的参数

output.log:我的程序的日志文件


在服务器的根目录中,期望找到prog.pid文件的位置在root用户的主目录下。 - undefined
不对,prog.pid文件位于“本地机器”,就是我执行ssh命令的地方。但问题不在这里。我有一个带有PID写入的prog.pid文件...只是PID不正确! - undefined
在第一个命令中,prog.id位于ssh命令的双引号之间,因此预期在远程执行。 - undefined
引号在我看来很好。 - undefined
我并没有说引号是错误的,但是这个命令没有按预期执行,因为默认情况下,作为第一个命令,它会在远程服务器的当前工作目录中创建一个文件,而不是root用户的主目录。 - undefined
2个回答

4
不要使用(command &) &。只需使用(command) &(或仅使用command &)。使用(command &) &,Bash需要fork另一个子shell来运行命令,因此$!将是子shell的PID而不是命令的PID。
请参见以下示例:
[STEP 124] # (nohup sleep 1234 > /dev/null 2>&1 &) &
[1] 44420      <=== this is the PID of the sub-shell which died immediately
[STEP 125] #
[1]+  Done                    ( nohup sleep 1234 > /dev/null 2>&1 & )
[STEP 126] # ps p 44420  <=== as you can see this PID does not exist any more
   PID TTY      STAT   TIME COMMAND
[STEP 127] # ps -C sleep u
USER        PID  TTY      STAT START   TIME COMMAND
root      44421  pts/13   S    17:48   0:00 sleep 1234
[STEP 128] # kill 44421
[STEP 129] #

这将很好地工作:
[STEP 131] # (nohup sleep 1234 > /dev/null 2>&1) &
[1] 44424         <=== this is the PID of the sleep command
[STEP 132] # ps p 44424 u
USER        PID  TTY      STAT START   TIME COMMAND
root      44424  pts/13   S    17:49   0:00 sleep 1234
[STEP 133] #

你是对的,我删除了&符号,PID是正确的。此外,你的回答完美地解释了发生的情况,非常感谢你。 - undefined

0

要在本地机器上写入带有远程pid的文件prog.pid,只需将重定向放在引号内部即可。

$SSH_COMMAND root@server "(nohup $PROG_CMD) & echo "'$!' > prog.pid

如果所需的进程ID是ssh本地进程,则必须将echo $!从ssh命令中取出。

$SSH_COMMAND root@server "(nohup $PROG_CMD)" & echo $! > prog.pid

不行,我试过了,什么都没改变。问题不在于将PID写入文件,而是要写入正确的PID! - undefined
你是否正确阅读了答案?因为问题中并不清楚哪个PID是有趣的,第一个命令给出了在远程服务器上执行的nohup命令的PID,而第二个命令则给出了本地ssh命令的PID。 - undefined
我对获取nohup命令的PID很感兴趣,我尝试了您的答案,将重定向从引号内部移出,并且prog.pid中的PID是11043,而我的程序的真实PID是11044。 - undefined
可能是由于最初的括号,它们启动了一个子shell,所以11043是远程shell进程的PID,而11044是子shell的PID,只需移除括号即可。 - undefined
我不确定,但是@whjm的答案解决了问题。 - undefined
我觉得你理解了$PROG_CMD在末尾加上了一个“&”,然后你通过移除这个“&”来修复了它。 - undefined

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