我试图理解此评论来自@sysfault:
/bin/sh -c 'echo $$>/tmp/my.pid && exec program args' &
我尝试了以下变化......
内外不同的$$:
/bin/bash -c 'echo $$ && exec sleep 5' ; echo $$
14408
29700
相同的 pid (但在后台):
$ /bin/bash -c 'echo $$ && exec sleep 5' & echo $!
[1] 8309
8309
$ 8309
[ 1 ]+ Done /bin/bash -c 'echo $$ && exec sleep 5'
$$ & $! 的不同 pid:
/bin/bash -c 'echo $$ && exec sleep 5 & echo $!'
6504
6503
杀死不起作用:/bin/bash -c 'echo $$ && (sleep 15 ; echo done)'
19063 Killed $ done(杀死后出现 echo)
与访问前台进程的 pid 相同的 pid:
$ /bin/bash -c 'echo > tmp.pid ; sleep 10 ; echo $$ ; echo done ; echo $$;'
28415 (instantly)
28415 (10 seconds later)
done
28415
$ cat tmp.pid
28415
使用此命令,我能够在睡眠完成之前在另一个窗口中杀死 pid - 从而防止最后三个回声发生:
$ /bin/bash -c 'echo $$ ; sleep 30 ; echo $$ ; echo done ; echo $$;'
23236
Killed
上下文:最终我想通过 php exec() 启动 bash 进程,并等待结果后再继续和保存 pid,这样我就可以清理,以防手动取消按钮被按下。我要处理 2 个昂贵的过程:一个是 rsync,另一个是 git commit & push。
可靠地获取包含多个命令(使用 ; > | 或 &&)的前台 bash 脚本的 pid 的最佳方法是什么?
答案1
$$
是当前外壳。在脚本主体中使用 $$ 时bash -c
,你将获得生成的 shell
$ echo $$; bash -c 'echo $$'; echo $$
6872
6987
6872
$!
是最后一个后台进程
$ sleep 5 & echo $!; sleep 5 & echo $!; echo ===; pgrep -l sleep
[1] 7118
7118
[2] 7119
7119
===
7118 sleep
7119 sleep
当您这样做时bash -c 'echo $$' & echo $!
,您会得到两次打印相同的 pid,因为对于您当前的 shell,$! 是后台 bash 进程的 pid,而在脚本主体内部,$$ 是同一后台 bash 进程的当前 pid。
当您这样做时/bin/bash -c 'echo $$ && exec sleep 5 & echo $!'
,您会得到两个不同的 pid:$$ 是 bash 进程的 pid,而 $! 是睡眠进程的 pid。
- 我觉得这很奇怪,因为你正在使用,
exec
所以它应该是相同的 PID(睡眠进程取代 bash 进程) - 但是你正在使用
exec ... &
所以 bash 必须首先 fork子壳运行后台任务,然后 exec 替换那个子壳睡眠。
您的实际问题最好由 php 人员来回答,而我不是。您应该向版主举报此问题,并请求将其移至 Stack Overflow,因为那里肯定会有更多 php 人员聚集。