web-dev-qa-db-ja.com

Bashの組み込みexecの使用例/実用例

Bashの組み込みexecのドキュメントからこれを考慮してください:

execは、新しいプロセスを作成せずにシェルを置き換えます

ユースケース/実用例を提供してください。これがどうして意味があるのか​​分かりません。

私はググって I/O redirection について見つけました。もっとよく説明できますか?

13
Ivanov

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のまったく異なる使用例であり、シェルを別のプロセスに置き換えることとは何の関係もありません。 execに次のように引数がない場合:

exec 3>>/tmp/logfile

その後、コマンドラインのI/Oリダイレクトは現在のシェルプロセスで有効になりますが、現在のシェルプロセスは実行を継続し、スクリプトの次のコマンドに移動します。

19
Celada

Shell execビルトインを使用して、プロセスID(PID)をJavaプログラムに取得しました。内部からPIDを取得する方法があるかもしれませんJavaですが、数年前はありませんでした。プロセスが独自のPIDを持つと、それをPIDファイルに書き出すことができます(「.pid」を含むファイル名については、_/var/run/_を参照してください)接尾辞)は、管理プログラムが実行中のプロセスのPIDを認識できるようにし、同じサーバーの2番目のインスタンスが実行されないようにします。次のように機能します。

_exec Java -cp=YourServer.jar StartClass -p $$
_

クラスStartClassmain()メソッドのコードは引数の解析を処理し、独自のプロセスIDを見つけることができます。

5
Bruce Ediger

楽しみのために、ユーザープロセスアカウンティングと制限があるシステムで、次のプログラム(選択した実装言語に翻訳)をバックグラウンドで実行します。

while(true) fork();

使用が許可されているプロセステーブルのすべてのスロットが、実行中のプログラムのコピーでいっぱいになったので、それをどのように強制終了しますか? kill(1)を起動するには、所有できない別のプロセススロットが必要です。シェルにkillコマンドを使用して自分自身を置き換えることは確かに便利です...

exec /bin/kill -9 -1

(システムが/ bin/killにkill(1)を持っていると仮定します。「exec `which kill` -9 -1」は潜在的に安全です。)これにより、SIGKILLが可能なすべてのプロセスに送信されます。

(注:プロセス制限により、シェルのプロセススロットに新しいログインが常に許可されている場合を除き、起動中のシェルからログアウトしないでください。これを行うと、クリーンアップが少し難しくなる可能性があります。 90年代初頭。いいえ。

2
Eric Towers
  • これは、プロセスのPIDを知る必要があるブルースの例に似ています。

    (cmdpid = $ BASHPID;(sleep 300; kill "$ cmdpid")&exec 長期実行コマンド

    あなたの中で

    1. サブシェル(外側(および))、
    2. サブシェルのPIDを調べます。 ($$は、メインシェルのPIDを提供します。)
    3. タイムアウト後にプロセスを強制終了するサブサブシェルを切り離し、
    4. 手順1で作成したサブシェルのプロセスでコマンドを実行します。

    これは実行されますlong-running-command、ただし、事前に決められた限られた時間のみ。

  • これは少し軽薄ですが、残りのログインセッションでroot(または他のユーザー)になりたい場合は、exec su

    実際、これが本当に役立つシナリオを想像できます。リモートシステムにログインしていて、何らかの理由で接続の切断と新しい接続の開始に問題があるとします。たとえば、リモートシステムにスケジュールに従っているファイアウォールがあるとします。接続したときに接続が許可され、確立された接続は閉じられませんが、現在、新しい接続は受け入れられていません。

    これで、やりたいことが完了し、ログアウトする準備が整いました。あなたの友達のボブはあなたと同じ部屋にいて、リモートシステムで何らかの作業をしたいと考えていますが、接続できません。したがって、exec su - bob、そしてパスワードプロンプトが表示されたら、ワークステーションを彼に向けます。現在、(バックグラウンドで何かを実行していない限り)UIDを使用したプロセスはないため、ボブはファイルをいじることができません。彼はあなたのつながりを効果的に引き継ぎます(あなたの同意と協力を得て)。

    ノート:

    • もちろん、これは、suの実行が許可されていない場合は機能しません。
    • ログに記録されるので、誰かに自分の動機を説明する必要があるかもしれません。ポリシー(ファイアウォールのスケジュール)を回避しているため、問題が発生する可能性があります。
    • 100%安全であることを保証しません。たとえば、whoにはおそらくあなたの名前が表示されます。一部の(不適切に記述された)プログラムがそれを使用して、ボブがあなたであると考え、彼にあなたのリソースへのアクセス権を与えることが考えられます。
    • システムが監査を行う場合、ボブのアクションはあなたの名前で監査される可能性があります。