Linuxで一時停止状態のプロセスを開始するにはどうすればよいですか?


19

実際には、Ctrl+Z開始直後に押すように動作するプロセスが必要です。

うまくいけば、シェルスクリプトを使用してそのようなことを行うことが可能です。

(また、結果のPIDを知ることは素晴らしいことなので、その後もプロセスを続行できます。)

回答:


7

プロセスを開始した後、SIGSTOPを送信して中断することができます。再開するには、SIGCONTを送信します。この小さなスクリプトがあなたを助けるかもしれないと思います

#!/bin/bash
$@ &
PID=$!
kill -STOP $PID
echo $PID
wait $PID

プロセスを実行し(コマンドをパラメーターとして送信)、プロセスを一時停止し、プロセスIDを出力して、終了するまで待機します。


1
最後に続行するように変更しました:[enter] #!/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
-java.is.for.desktop

7
ご存知のように、サブプロセスは、STOPシグナルを送信する機会を得る前に終了する場合があります。
MikeyB

16
レースの別の日。
ctrl-alt-delor

23

どの環境からプロセスを作成していますか?

Cコードなどの環境から実行している場合は、fork()を実行してから、子でexec()の前に自分にSIGSTOPを送信し、それ以上実行できないようにします。

より一般的なソリューション(おそらく最良)は、そうするスタブを作成することです。したがって、スタブプログラムは次のようになります。

  • 実際のプログラムの名前と引数で構成される引数を取る
  • SIGSTOPを自分自身に送信する
  • exec()適切な引数を持つ実際のプログラム

これにより、シグナルを送信する前に新しい処理が過度に行われることに関係する、あらゆる種類の競合状態を回避できます。


シェルの例:

#!/bin/bash
kill -STOP $$
exec "$@"

上記のcodezを使用して:

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 -lPIDを示しています。ただし、シェルから実行する場合は、PIDを直接必要としません。次のことができます:(kill -CONT %1ジョブが1つしかない場合)。

複数の仕事でそれをしますか?読者のための演習として残した:)


これをシェルスクリプトから実行したいと考えていました
...-java.is.for.desktop

すばらしい。だからシェルスクリプトからこれを行いたいので、スタブプログラムを使用してください。
MikeyB

20

MikeyBの答えは正しいです。スーパーユーザーに関するこの質問から、より簡潔なバージョンを以下に示します。

( kill -SIGSTOP $BASHPID; exec my_command ) &

これを理解するには、unix上でプロセスがどのように開始されるかを理解する必要があります。execシステムコールは、現在実行中のプログラムを新しいもの置き換え、既存のPIDを保持します。したがって、独立したプロセスを作成する方法は、最初forkに、次にexec、子プロセスで実行中のプログラムを目的のプログラムに置き換えることです。

このシェルコマンドの構成要素は次のとおりです。

  1. 括弧はサブシェルを(...)開始します:BASHの別のインスタンス。
  2. このkillコマンドは、このプロセスにSTOPシグナルを送信し、プロセスを一時停止状態にします。
  3. CONTシグナルを送信することにより)プロセスの続行を許可するとすぐに、execコマンドにより、目的のプログラムに置き換えられます。 my_commandサブシェルの元のPIDを保持します。
  4. $!変数を使用して、プロセスのPIDを取得できます。

2
基本的に正しいので、これが好きです(ちょうどの-s STOP代わりに使用しなければならなかったということです-SIGSTOP)。まだ不思議です:なぜそれの$BASHPID代わりになければならないの$$ですか?(違いを本当に理解していないかもしれません)。
Hibou57 14

1
ための$$$BASHPID、私は前者はないが、後者は、サブシェルのPIDであるチェック。面白い問題があります:bashスクリプトにヒントを適用すると、ほとんどの場合失敗し、次のようなPID=$!; ps -p $PID; kill -s CONT $PID;ことをしなければなりません:... ps -p $PIDパーツを削除すると失敗します。 。対話型シェルからでも問題ありません。問題はスクリプトからのみです。それはあまりにも神秘的です。
Hibou57 14

my_commandのファイル記述子をリストするためにこのソリューションを使用しようとしました。(goo.gl/cNbUE8)が、記述子は同じままです。
rasty.g

$BASHPIDbash以外のシェルの代替オプションについては、こちらを
Jakob
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.