web-dev-qa-db-ja.com

bash "exec 1>&2"コマンドを理解する

関数にexec 1>&2コマンドが含まれているbashスクリプトを見ました。何かのようなもの:

function example()
{
    exec 1>&2
    cat <<EOT
Script requires at least one parameter.
EOT
    exit 1
} 

私が理解しているように、exec 1>&2は、この時点からすべてがstderrに転送されることを意味します。これは、execのある種の固定された動作であり、心から知る必要がありますか、それともこの背後にある適切な説明がありますか?私が理解しているように、Bashスクリプトのexecは、Bashスクリプトが持っていたのと同じPIDを取得してコマンドを呼び出すだけです。 コマンドが終了すると、PIDが強制終了されます。 1>&2はコマンドではありません。誰かがexec 1>&2コマンドの背後にある詳細(特になぜの質問)を説明できますか?

13
Martin

execは組み込みのBash関数であるため、外部プログラムでは不可能な特別な動作をすることができます。特に、次のような特別な動作があります。

COMMANDが指定されていない場合、リダイレクトは現在のシェルで有効になります。

(それはhelp execによって与えられたメッセージからの引用です。)

これは、あらゆる種類のリダイレクトに適用されます。たとえば、次のいずれかを記述することもできます。

exec >tmp.txt
exec >>stdout.log 2>>stderr.log
exec 2>&1

(ただし、notはパイプに適用されます。)

20
ruakh

なぜ歴史の事故なのか、大きな理由はありません。

リダイレクト演算子は任意のプログラム(たとえば、cat)に適用され、>&形式が追加されて、「2から1の重複ファイル記述子」を表現できるようになりました。 >&構文は、特殊文字が不足していて、>&&の基本的な意味を考えると、>は意味がないため、おそらく使用されました(ただし、引用しないでください)それ)。これはすべて1977年頃の初期のボーンシェルにまでさかのぼります。

なぜexecに加えて、現在のシェルの入力と出力を変更するためのリダイレクトがあるのですか?おそらく、nullコマンド> pathには、cat /dev/null > pathと同じ効果がありますが、入力が簡単な意味がすでにあり、テレタイプがせいぜい1秒あたり10文字で実行された場合、それは重要でした。そのため、execビルトインはオーバーロードされました。引数なしで、リダイレクト操作をそれ自体に適用しました。

BashはBourneShellの規則を可能な限り順守しようとするため、これらの古美術品を入手できます。これは、おそらく、適切な性別の他のメンバーに印象を与えようとしている場合は特に覚えておく必要があります(つまり、「ひよこは男を掘る彼のI/Oリダイレクトアルカナを知っています」)。

12
msw

元のソース: http://tldp.org/LDP/abs/html/x17784.html

Exec <filenameコマンドは、stdinをファイルにリダイレクトします。その時点から、すべてのstdinは、通常のソース(通常はキーボード入力)ではなく、そのファイルから取得されます。これにより、ファイルを1行ずつ読み取り、場合によってはsedやawkを使用して入力の各行を解析する方法が提供されます。

同様に、exec> filenameコマンドは、stdoutを指定されたファイルにリダイレクトします。これにより、通常はstdoutに送られるすべてのコマンド出力がそのファイルに送信されます。

Exec N> filenameは、スクリプト全体または現在のシェルに影響することに注意してください。その時点からのスクリプトまたはシェルのPIDのリダイレクトが変更されました。ただし、N> filenameは、スクリプト全体またはシェルではなく、新しくフォークされたプロセスにのみ影響します。

興味のある詳細情報は@ http://tldp.org/LDP/abs/html/io-redirection.html にあります。あなたができる素敵な小さなリダイレクトのトリックがたくさんあります。

3