实际上,我需要一个行为正常的过程,就像我Ctrl+Z
刚开始按下它一样。
希望有可能使用Shell脚本来执行此操作。
(另外,知道生成的PID很好,因此我以后可以继续执行该过程。)
实际上,我需要一个行为正常的过程,就像我Ctrl+Z
刚开始按下它一样。
希望有可能使用Shell脚本来执行此操作。
(另外,知道生成的PID很好,因此我以后可以继续执行该过程。)
Answers:
启动进程后,可以将其发送给SIGSTOP以将其挂起。要恢复它,请发送SIGCONT。我认为这个小脚本可能对您有帮助
#!/bin/bash
$@ &
PID=$!
kill -STOP $PID
echo $PID
wait $PID
它运行进程(命令send作为参数),将其挂起,打印进程id并等待其结束。
您是从哪个环境创建流程的?
如果是从C代码等环境中进行操作,则可以fork(),然后在子级中,在exec()之前向自己发送SIGSTOP,以防止进一步执行。
一个更通用的解决方案(可能是最好的)将是创建一个这样做的存根。因此,存根程序将:
这将确保您避免与新处理有关的任何竞争情况都无法在您向其发送信号之前走得太远。
一个shell的例子:
#!/bin/bash
kill -STOP $$
exec "$@"
并使用上面的代码:
michael@challenger:~$ ./stopcall.sh ls -al stopcall.sh
[1]+ Stopped ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$ jobs -l
[1]+ 23143 Stopped (signal) ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$ kill -CONT 23143; sleep 1
-rwxr-xr-x 1 michael users 36 2011-07-24 22:48 stopcall.sh
[1]+ Done ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$
在jobs -l
示出了PID。但是,如果您是从Shell进行操作,则不需要直接使用PID。您可以这样做:(kill -CONT %1
假设您只有一份工作)。
要做一项以上的工作?留给读者练习:)
MikeyB的答案是正确的。从这个问题上的超级用户,这里有一个更简洁的版本:
( kill -SIGSTOP $BASHPID; exec my_command ) &
要理解这一点,需要了解如何在UNIX上启动进程:exec
系统调用将使用新程序替换当前正在运行的程序,并保留现有的PID。因此,创建独立进程的方法是:首先fork
,然后exec
用所需程序替换子进程中正在运行的程序。
此shell命令的成分是:
(...)
开始一个子外壳:BASH的另一个实例。kill
命令将STOP信号发送到该进程,从而使其进入挂起状态。CONT
信号),该exec
命令就会使它用所需的程序替换。 my_command
保留子外壳的原始PID。$!
变量获取进程的PID。-s STOP
代替-SIGSTOP
)。仍然奇怪:为什么必须$BASHPID
代替它$$
?(我可能不太了解其中的区别)。
$$
vs $BASHPID
,我检查后者是子外壳的PID,而不是前者。有一个有趣的问题:在bash脚本中应用提示,大多数情况下会失败,并且我必须执行以下操作:PID=$!; ps -p $PID; kill -s CONT $PID;
…如果我删除了该ps -p $PID
部件,它将失败:该过程似乎消失了(杀死了?),而没有任何错误消息。从交互式外壳程序可以,问题仅在于脚本。太神秘了。
#!/bin/bash
[enter]$@ &
[enter]PID=$!
[enter]kill -STOP $PID
[enter]echo "Suspended: $PID, press ENTER to continue it"
[enter]read
[enter]kill -CONT $PID
[enter]wait $PID
[enter]echo