スクリプトのリダイレクト

スクリプトのリダイレクト

私はショートシェルスクリプティングビデオコースを受講しており、提供された例の1つは次のとおりです。

if [[ ! $1 ]]; then
    echo "Need line length argument" >&2
    exit 1
fi

コース資料には、「これは標準エラーでエラーを印刷します」と記載されています。しかし、それは私の限られた理解には合いません。デフォルトのファイル記述子(指定されていない場合)は「1」です(したがって、この場合はstdout、つまり次のようになります)。上記1>&2)。これはstdoutをstderrにリダイレクト/マージするようです。

リダイレクトの一部として「&」がどのように機能するかについての情報がありませんか?

ベストアンサー1

それはただ誤解でした。 「これは、エラーを標準エラーとして印刷することです。」は、「標準エラーは出力が終わる場所です」を意味します。そうですね。 「stdoutをstderrにリダイレクト/マージ」です。しかし、これは矛盾ではありません。

コマンドはこの変更を認識しません。このコマンドはstdout(例:fd 1)として印刷されます。ただし、コマンドを実行する前にシェルがstdout作成されますstderr

$ strace -f bash -c '/bin/echo foo >&2'
[...]
dup2(1, 2)                  = 2
fcntl(1, F_GETFD)           = 0
execve("/bin/echo", ["/bin/echo", "foo"], 0x55ffb063e5d0 /* 103 vars */) = 0
[...]

man 2 dup

int dup2(int oldfd, int newfd);
dup()システムコールは、最も低い番号の未使用のファイル記述子を新しい記述子として使用して、ファイル記述子oldfdのコピーを作成します。
正常に戻ったら、古いファイル記述子と新しいファイル記述子を入れ替えて使用できます。これらは同じオープンファイル記述(open(2)を参照)を参照するため、ファイルオフセットとファイルステータスフラグを共有します。たとえば、ファイルディスクリプタの1つでファイルオフセットを変更するためにlseek(2)を使用すると、もう1つはファイルディスクリプタのオフセットも変更されます。
両方のファイル記述子はファイル記述子フラグ(close-on-execフラグ)を共有しません。重複した記述子のclose-on-execフラグ(FD_CLOEXEC; fcntl(2)を参照)がオフになります。

おすすめ記事