execコマンドの可能な使用法は何ですか?


10

私はexecコマンドを学んでいます。execコマンドが、それを開始したプロセスを置き換えることを知っています。したがって、execコマンドに置き換えられたプロセスに戻ることはできません。

その目的は、それを開始したプロセスに戻ることを不可能にすることであると言えるでしょう。

しかしexec、コマンドとして使用できるようなものを使用する他の用途は何ですか?



1
ウィキペディアの記事から:「ラッパースクリプトは、このコマンドを使用して、環境変数やその他の構成を設定した後、プログラムを(直接またはインタープリターや仮想マシンを介して)実行することがよくあります。」
knb


2
個人exec ssh server-that-does-byobu-on-login.example.com的には、^ A ^ Dがターミナルを完全にシャットダウンするという点で、非常に喜ばしいことです。(より一般的には、exec byobu(またはexec screenexec tmux)。
Willihamトットランド

回答:


9

ラッパースクリプト

exec 主にラッパースクリプトで使用されます。

メインプログラムを実行する前にプログラムの環境を変更する場合は、多くの場合、スクリプトを記述し、その最後にメインプログラムを起動します。ただし、その時点でスクリプトをメモリに保持する必要はありません。したがって、execこれらのケースで使用されているため、メインプログラムはマザースクリプトを置き換えることができます。

これはその実用的な例です。それのmate-terminal.wrapperスクリプトは、仲間端子が付属しています。これは、mate-terminalユーザーの環境をチェックすることにより、いくつかの追加の引数から始まります。

#!/usr/bin/perl -w

my $login=0;

while ($opt = shift(@ARGV))
{
    if ($opt eq '-display')
    {
        $ENV{'DISPLAY'} = shift(@ARGV);
    }
    elsif ($opt eq '-name')
    {
        $arg = shift(@ARGV);
        push(@args, "--window-with-profile=$arg");
    }
    elsif ($opt eq '-n')
    {
        # Accept but ignore
        print STDERR "$0: to set an icon, please use -name <profile> and set a profile icon\n"
    }
    elsif ($opt eq '-T' || $opt eq '-title')
    {
        push(@args, '-t', shift(@ARGV));
    }
    elsif ($opt eq '-ls')
    {
        $login = 1;
    }
    elsif ($opt eq '+ls')
    {
        $login = 0;
    }
    elsif ($opt eq '-geometry')
    {
        $arg = shift(@ARGV);
        push(@args, "--geometry=$arg");
    }
    elsif ($opt eq '-fn')
    {
        $arg = shift(@ARGV);
        push(@args, "--font=$arg");
    }
    elsif ($opt eq '-fg')
    {
        $arg = shift(@ARGV);
        push(@args, "--foreground=$arg");
    }
    elsif ($opt eq '-bg')
    {
        $arg = shift(@ARGV);
        push(@args, "--background=$arg");
    }
    elsif ($opt eq '-tn')
    {
       $arg = shift(@ARGV);
       push(@args, "--termname=$arg");
    }
    elsif ($opt eq '-e')
    {
        $arg = shift(@ARGV);
        if (@ARGV)
        {
            push(@args, '-x', $arg, @ARGV);
            last;
        }
        else
        {
            push(@args, '-e', $arg);
        }
        last;
    }
    elsif ($opt eq '-h' || $opt eq '--help')
    {
        push(@args, '--help');
    }
}
if ($login == 1)
{
    @args = ('--login', @args);
}
exec('mate-terminal',@args);

ここで注目すべき点は、execメモリ内でこのスクリプトを置き換える呼び出しがあることです。

Unix&Linux StackExchangeサイト-https : //unix.stackexchange.com/q/270929/19288で回答された同様の質問は次のとおりです

ファイル記述子をリダイレクトするには

のもう1つの一般的な用途execは、ファイル記述子のリダイレクトです。stdinstdoutstderrのexecを使用してファイルにリダイレクトすることができます。

  1. リダイレクトstdout- exec 1>file標準出力をfile、現在のシェルセッションの終了時に指定されたファイルにします。ディスプレイに出力するものはすべてファイルに含まれます。

  2. リダイレクトstdin- stdinファイルへのリダイレクトにも使用できます。たとえば、スクリプトファイルを実行するscript.sh場合は、stdinを使用してにファイルをリダイレクトできますexec 0<script.sh


はい。その後 'mate-terminal'はラッパースクリプトが持つPIDを持っていますか?そして、ラッパースクリプトが使用したメモリを使用しますか?そのため、ラッパースクリプトは消滅しました。それ以外の場合、2つのスクリプトはシステム上に(2つの異なるPIDを持つ)別のプロセスとして存在しますか?
mizech 2016

@mizechはい。彼らは同じPIDを使用しています
Anwar

@mizech喜んでそれが役に立ったことを知った:)
Anwar

1
すばらしい例、それが本当に明確になります
Zanna

この回答は部分的なものであり、execファイル記述子のリダイレクトでの使用という重要な(そして典型的な)使用の1つを逃しています。
heemayl 2016

9

この exec コマンドは、現在のシェルプロセスを指定されたコマンドに置き換えます。通常、コマンドを実行すると、新しいプロセスが生成(フォーク)されます。exec コマンドは、新しいプロセスを生成しません。代わりに、現在のプロセスが新しいコマンドでオーバーレイされます。つまり、exec新しいプロセスを作成することなく、現在のシェルの代わりにコマンドが実行されます。

execコマンドの最も一般的な使用法は3つあります。

1.プロセスの入れ替え

例1: 新しいbashシェルを次のように開いた場合

$ bash 

pstree、それは次のようになります

├─gnome-terminal
        ├─bash───bash───pstree

以前のbashシェルはまだ残っており、新しいbashシェルを入手しました。一方、新しいbashシェルを開くと、

$ exec bash

pstreeショー

├─gnome-terminal
        ├─bash───pstree

ここで古いものbashが新しいものに置き換えられます。1つのコマンドで複数のログインを終了することは特に便利です。それはより安全で、誤って開いたターミナルを離れる可能性をなくします。1つのコマンドでrootとユーザーの両方終了するを参照してください

例2:ファイルを次のように開くことができます

$ exec vi filename.txt

あなたが終了するとvi、シェルがすでに交換されると別途の端末を閉鎖する必要はありません。viを閉じるとすぐにターミナルも閉じられます。

2.シェルスクリプト内でファイル記述子をリダイレクトする方法

このexec コマンドは、ファイル記述子を動的に開いたり、閉じたり、コピーしたりするシェルスクリプトでも使用できます。これにより、コマンド呼び出し文字列ではなく、シェルスクリプト内のさまざまなファイルへのSTDIN、STDERR、STDOUTおよびその他のファイル記述子のリダイレクトを実行できます。コマンドまたは引数を指定しない場合は、リダイレクトシンボルとファイル記述子を指定して、これらの機能を実行できます。

script.shログファイルを作成したいシェルスクリプトがあるとしますscript.log。次のように使用できますexec

LOG=/path/to/script.log
exec 1>>$LOG
exec 2>&1

これは

./script &>> /path/to/script.log
./script >>  /path/to/script.log 2>&1

3. execコマンドを使用してプロセスのステージを作成する

また、execコマンドを使用して、プロセスのステージのように互いに順次実行する一連のシェルスクリプトを作成することもできます。コントロールを次のスクリプトに転送する必要があるたびに新しいプロセスを生成する代わりに、execコマンドを実行します。

この場合、各ステージの最後のステートメントexecは、次のステージを呼び出すコマンドでなければなりません。

詳細についてexec、シェルスクリプトでのコマンドの使用を参照してください。

注:上記の一部はこれから取得されます。


1
(これまでのところ)完全な回答のみ。
heemayl 2016

私がexecを使用したすべての時間は、効率のためです。execを使用してデーモンを実行する場合、必要なアクティブプロセスは2つではなく1つだけです。特にbashプロセスを離れると、数MBのRAMが無駄になります。
gmatht 2016

2

私が知る限り、bashスクリプトのファイル記述子(たとえば、STDOUT、STDERR、STDIN)をリダイレクトするためにも使用されます。

したがって、たとえば、STDINリダイレクトを使用してキーボードからではなくファイルから読み取り、STDOUT(またはプログラムによってはSTDERR)リダイレクトによって端末ではなくファイルに書き込むことができます。


1
この回答は部分的であり、この回答を補足するだけです。
heemayl 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.