
私はMacBookを持っています(デフォルトのシェルはzshです)
実行可能なPythonスクリプトがあります(script1.py)。
私は次のような他の実行可能なスクリプトを使用します。起動機)走るscript1.py マイコンピュータが起動したときに実行されるターミナルウィンドウ起動機自動的に開閉し、script1.pyプロセスはまだ別のプロセスとして実行されます。 (起動機私のコンピュータの電源を入れると、szhシェルインスタンスを介して自動的に実行されます。オリジナル起動機スクリプトファイルは次のとおりです。
#!/bin/bash
cd /script1; nohup ./script1.py &
このスクリプトはうまく実行され、すべてがうまくいきます。
しかし、スクリプトで(;)の代わりに(&&)を使用すると、何が起こるのかを理解しようとしています。つまり
#!/bin/bash
cd /scritp1 && nohup ./script1.py &
私の問題はこれもうまくいきますが、Pythonスクリプトのプロセスを終了しようとするたびにszhまたは他のもの(おそらくbashプロセス)の端末インスタンスがプロセスとして実行されていることです。つまり、私が電話するとメモターミナルで私は得る
ps -ef | grep "script1"
123 14679 1 0 2:12PM ?? 0:00.00 /bin/bash /script1 starter
123 14680 14679 0 2:12PM ?? 0:03.46 /PythonFolder/python ./script1.py
123 14690 14683 0 2:12PM ttys000 0:00.00 grep scrip1
スクリプト用起動機使用&&
そして
ps -ef | grep "script1"
123 14644 1 0 2:08PM ?? 0:03.46 /PythonFolder/python ./script1.py
123 14652 14647 0 2:08PM ttys000 0:00.00 grep scrip1
~のため起動機スクリプトの使い方;
あるバージョンには2つのプロセスがあり、他のバージョンには1つしかないのはなぜですか? szhが実行される理由を理解しようとしています。起動機使用時にPythonスクリプトを実行するサブプロセスを作成します。&&私の起動スクリプトが次を使用すると終了するのはなぜですか?;Pythonスクリプトを単一のプロセスとして実行するようにします。
私が走るとき起動機使用されたスクリプトとして&&ターミナルアプリケーションが表示されて閉じますが、2つの実行中のプロセス(14679そして14680この場合)。
私が使うなら起動機スクリプトの使い方;python.pyプロセスを終了したいです。ただ呼び出します。
kill 14644
しかし、私が使うなら起動機使用されたスクリプト&&2つのプロセスを終了したいです。子プロセスを終了するか、親プロセスを終了すると、子プロセスが機能することがわかりました。
kill 14680
または
kill 14679; kill 14680
私も親プロセスを殺すことができることがわかりました。
kill 14679
私のPythonスクリプトは通常どおり実行され続けます。
答え1
鍵はどのようにコマンドリスト#!/bin/bash
動作します(shebangラインを使用しているので、ここからBashマニュアルを引用してください):
リストは演算子 ';'、'&'、'&&'、または '||'いずれかで区切られ、オプションで ';'、'&'、または新しい行が先頭にある 1 つ以上のパイプシーケンスです。
これらのリスト演算子の中で、&&と||は同じ優先順位を持ち、次に同じ優先順位を持ちます。
(まだ残っています。管路|
または)で区切られた1つ以上のコマンドシーケンス|&
。
これは次のことを意味します。
cd /script1; nohup ./script1.py &
演算子間の優先順位規則のために、シェルcd /script1
はによって終了されたリストを確認し、;
「デフォルト」シェルで同期的に実行され、リストnohup ./script1.py
はによって終了し、&
生成された別のプロセスで非同期的に実行されます。
一方、
cd /scritp1 && nohup ./script1.py &
シェルはANDリストを確認しcd /scritp1 && nohup ./script1.py
て終了し、&
リスト全体を非同期的に実行します。これをbash
行うには、リスト自体を(バックグラウンドで)実行するための新しいプロセスを作成する必要があります。これは、Pythonスクリプト用の別々のプロセスを生成します。
情報kill
: 親プロセスの終了子プロセスは自動的に終了しません。。これは標準シェル動作です。 listの場合、&&
子プロセスを終了すると親プロセスが終了する可能性があります。親プロセスが実行するすべての操作は、子プロセスが返されるのを待っているためです。
nohup ./script1.py
成功に応じて条件付きで実行したい場合cd /script1
そしてANDリストのシェルの作成を防ぐには、2番目の要素大きな括弧:
cd /scritp1 && { nohup ./script1.py & }
または条件付きブロックを使用します。
if
cd /scritp1
then
nohup ./script1.py &
fi
答え2
親プロセスに依存しないプロセスを作成する簡単な方法を見つけました。
(<command here> &)
これにより、コマンドを実行する別の背景シェルを生成する新しいシェルが作成されます。上記のコマンドが実行されるデフォルトのシェルを閉じても、プロセスは停止しません。このコマンドを実行するプロセスのPPID(init)は1です。
これは、2番目のシェルが3番目のシェルの親プロセスであり、子プロセスが完了するのを待たずに実行を完了するためです(唯一の作業は3番目のシェルを作成することです)。その後、子供は孤児となり、initによって処理されます。
上記のようにここ
プロセスは、再割り当てに使用したリソースを解放する_exitシステムコールを使用して終了できます。したがって、プロセスが終了する準備ができたら、終了ステータスという情報を使用してプロセスが終了した理由をカーネルに通知します。最も一般的に、状態0は、プロセスが成功したことを示します。ただし、これはプロセスを完全に終了するのに十分ではありません。親プロセスは子プロセスの終了を確認するために待機システムコールを使用する必要があります。その機能は、子プロセスの終了状態を確認することです。考えるのが怖いのは分かりますが、電話を待つことは必須です。結局のところ、子供がどのように死んだのか知りたくない親はどこにありますか?
孤児プロセス
親プロセスが子プロセスの前に終了すると、カーネルは待機呼び出しを受け取らないことがわかっているので、そのプロセスを「孤立」にし、initの管理下に置きます(すべてのプロセスの母親を覚えてください)。 Initは最終的にこれらの孤児が死ぬことができるようにスタンバイシステムコールを実行します。
ゾンビプロセス
子プロセスが終了し、親プロセスがまだ待機を呼び出していない場合はどうなりますか?私たちはまだ子プロセスがどのように終了するかを確認できるようにしたいので、子プロセスが完了してもカーネルはサブプロセスをゾンビプロセスに切り替えます。子プロセスで使用されているリソースはまだ別のプロセスに解放できますが、プロセステーブルにはまだゾンビプロセスのエントリがあります。ゾンビプロセスも技術的に「死んだ」ので終了できないため、信号を使用して終了することはできません。最終的に親プロセスがwaitシステムコールを呼び出すと、ゾンビプロセスは消えます。これを「収穫」といいます。親プロセスがスタンバイコールを実行しない場合、initはゾンビを採用し、自動的にスタンバイを実行し、ゾンビを削除します。ゾンビプロセスが多すぎると、プロセステーブルのスペースを占有し、プロセステーブルがいっぱいになると他のプロセスが実行されなくなるため、問題が発生する可能性があります。