Bashの組み込みexecのドキュメントからこれを考慮してください。
execは、新しいプロセスを作成せずにシェルを置き換えます
ユースケース/実用例を提供してください。これが理にかなっているのかわかりません。
私はグーグルでI / Oリダイレクトについて知りました。もっと説明してもらえますか?
Bashの組み込みexecのドキュメントからこれを考慮してください。
execは、新しいプロセスを作成せずにシェルを置き換えます
ユースケース/実用例を提供してください。これが理にかなっているのかわかりません。
私はグーグルでI / Oリダイレクトについて知りました。もっと説明してもらえますか?
回答:
exec多くの場合、主に他のバイナリを起動するためのラッパーとして機能するシェルスクリプトで使用されます。例えば:
#!/bin/sh
if stuff;
EXTRA_OPTIONS="-x -y -z"
else
EXTRA_OPTIONS="-a foo"
fi
exec /usr/local/bin/the.real.binary $EXTRA_OPTIONS "$@"
ラッパーの実行が終了すると、「実際の」バイナリが引き継がれ、プロセステーブルの同じスロットを一時的に占有したラッパースクリプトのトレースはなくなります。「実際の」バイナリは、孫ではなく、それを起動したものの直接の子です。
質問でI / Oリダイレクトについても言及しています。これはまったく別の使用例でexecあり、シェルを別のプロセスに置き換えることとは関係ありません。when execに引数がない場合、次のようになります。
exec 3>>/tmp/logfile
コマンドラインでのI / Oリダイレクトは現在のシェルプロセスで有効になりますが、現在のシェルプロセスは実行を続け、スクリプト内の次のコマンドに進みます。
execます。シェルは、子プロセスでアクション(コマンドの実行またはリダイレクトの実行)を実行せず、同じプロセスで実行するように指示します。
シェルのexec組み込みコマンドを使用して、JavaプログラムのプロセスID(PID)を取得しました。現在、Java内部からPIDを取得する方法があるかもしれませんが、数年前にはありませんでした。プロセスが独自のPIDを/var/run/取得すると、それをPIDファイルに書き込み(拡張子が「.pid」のファイル名を探す)、管理プログラムが実行中のプロセスのPIDを認識し、2番目のインスタンスを防止同じサーバーの実行。次のように機能します。
exec java -cp=YourServer.jar StartClass -p $$
main()クラスのメソッドのコードはStartClass引数の解析を処理し、独自のプロセスIDを見つけることができます。
楽しみのために、ユーザープロセスのアカウンティングと制限があるシステムでバックグラウンドで次のプログラム(選択した実装言語に翻訳されています)を実行します。
while(true) fork();
使用が許可されているプロセステーブル内のすべてのスロットが、実行中のプログラムのコピーでいっぱいになったので、どうやってそれを殺すつもりですか?kill(1)を起動するには、別のプロセススロットが必要ですが、これは使用できません。シェルを強制終了コマンドで置き換えると便利です...
exec /bin/kill -9 -1
(システムに/ bin / killにkill(1)があると仮定します。「exec `which kill` -9 -1」の方が安全である可能性があります。)これにより、可能なすべてのプロセスにSIGKILLが送信されます。
(注:プロセスの制限により、シェルのプロセススロットへの新しいログインが常に許可されない限り、起動シェルからログアウトしないでください。これを行うと、クリーンアップが少し難しくなる可能性があります。 90年代初期。いや。)
execこの状況で役立つコマンドを実際に示した場合、この答えは少し良くなります。(2)この答えはやや古風です。killコマンドは、主な理由は、この懸念のため、長年にわたりbashで組み込みコマンドとなっています。
exec— killビルトインであるという事実は、ビルトインとは何の関係もありませんexec。
`which kill`も機能しません。(2)ところで、$(…)フォームはフォームよりも推奨され`…`ます。(3)しかし、ディレクトリを推測することは危険ではありません。誤ってを入力するexec /binn/killと、エラーメッセージが表示されるだけで、シェルは消えません。(4)しかし、あなたも、どのようなディレクトリを心配する必要はありませんkillである。 exec用途$PATH、ちょうど通常のコマンドのように、そのexec kill …(あなたが持っていると仮定すると作品/bin検索パスに)。
これは、プロセスのPIDを知る必要があるブルースの例に似ています。
(cmdpid = $ BASHPID;(sleep 300; kill "$ cmdpid")&exec long-running-command)
あなたが
(と))を開始し、$$メインシェルのPIDを提供します。)これはを実行しますlong-running-commandが、事前に決められた限られた時間だけです。
これは少し簡単ですが、ログインセッションの残りの部分でroot(または他のユーザー)になりたいと判断した場合は、できexec suます。
実際、これが本当に役立つシナリオを想像できます。リモートシステムにログインしており、何らかの理由で接続の切断と新しい接続の開始に問題があると仮定します。たとえば、リモートシステムにスケジュールに従うファイアウォールがあるとします。接続すると接続が許可され、確立された接続は閉じられませんが、現時点では、新しい接続は受け入れられません。
やりたいことをやり終えて、ログアウトする準備ができました。友人のボブが部屋にいて、リモートシステムで作業をしたいと思っていますが、接続できません。したがって、と入力しexec su - bob、パスワードプロンプトが表示されたら、ワークステーションを彼に引き渡します。(バックグラウンドで何かを実行していない限り)UIDを使用したプロセスはないため、Bobはファイルをいじることができません。彼は(あなたの同意と協力を得て)あなたのつながりを効果的に引き継いだでしょう。
ノート:
su。whoおそらくまだあなたの名前が表示されます。一部の(不適切に作成された)プログラムがそれを使用してBobがあなたであると考え、彼にあなたのリソースへのアクセスを許可することは考えられます。(a;b)が(a;exec b)サブシェルの最後のコマンドのフォークを最適化するのと同じであることに注意してください。唯一の例外はあるように見えるbashとmksh。使用execすると、それを保証するのに役立ちます。