15

私はBashの初心者ですが、最近、コンピューターで仕事をするためにこのツールを学ぼうとしています。

私は今、ファイル記述子について自分自身に教えようとしています。私の実験のいくつかを共有させてください:


#!/bin/bash

# Some dummy multi-line content
read -d '' colours <<- 'EOF'
        red
        green
        blue
EOF

# File descriptor 3 produces colours
exec 3< <(echo "$colours")

# File descriptor 4 filters colours
exec 4> >(grep --color=never green)

# File descriptor 5 is an unlimited supply of violet
exec 5< <(yes violet)

echo Reading colours from file descriptor 3...
cat <&3
echo ... done.

echo Reading colours from file descriptor 3 again...
cat <&3
echo ... done.

echo Filtering colours through file descriptor 4...
echo "$colours" >&4
echo ... done. # Race condition?

echo Dipping into some violet...
head <&5
echo ... done.

echo Dipping into some more violet...
head <&5
echo ... done.

上記からの出力を見ると、いくつかの質問が思い浮かびます。

  1. fd3は「消費」後に「使い果たされる」ようですが、最初の使用後にも自動的に閉じられますか?
  2. fd3は名前付きパイプとどう違うのですか?(私がすでに見たもの)
  3. コマンドの実行はいつ開始されますか?yesfd宣言時に?後で?
  4. より多くのバイオレットが必要になったときにyes停止(CTRL-Zまたはその他)して再開しますか?
  5. のPIDを取得するにはどうすればよいyesですか?
  6. 「アクティブな」fdsのリストを取得できますか?
  7. fd4を介したフィルタリングに関する非常に興味深い競合状態、回避できますか?
  8. yes私が停止したときにのみ停止しますexec 5>&-か?
  9. 私が閉じるかどうかは重要です>&-<&-

とりあえずここでやめます。

ありがとう!

PS:部分的な(番号付きの)答えは大丈夫です..私は自分でさまざまな断片をまとめます..(一人からの包括的な答えは印象的ですが!)

4

1 に答える 1

15

fd3は「消費」後に「使い果たされる」ようですが、最初の使用後にも自動的に閉じられますか?

いいえ、閉鎖されていません。これは、exec動作方法によるものです。使用したモードexec(引数なし)では、その機能は、シェル自体に指定されたI / Oリダイレクトによって要求されたシェル自体のファイル記述子を配置し、スクリプトが終了するか、再び変更されるまでそのままにします。後で。

後で、catこのファイル記述子3のコピーを標準入力(ファイル記述子0)で受け取ります。catの標準入力は、終了時に暗黙的に閉じられcatます(または、可能性は低いですcatが、存在する前に閉じますが、それは問題ではありません)。シェルのファイル記述子3である、このファイルの元のコピーは残ります。実際のファイルはEOFに達しており、それ以上何も読み取られません。

fd3は名前付きパイプとどう違うのですか?(私がすでに見たもの)

シェルの<(some command)構文(これは標準のBourneシェル構文ではなく、zshとでのみ使用可能であると私は信じていますbash)は、実際には名前付きパイプを使用して実装される可能性があります。(を使用して)より良い方法があるため、おそらくLinuxにはありません/dev/fdが、おそらく他のオペレーティングシステムにあります。

したがって、その意味で、この構文は名前付きパイプを設定するためのヘルパーである場合とそうでない場合があります。

コマンドyesはいつ実行を開始しますか?fd宣言時に?後で?

<(yes violet)コンストラクトが評価されるとすぐに(これは、exec 5< <(yes violet)が評価されたときに発生します)。

はい(CTRL-Zまたはその他)停止し、さらにバイオレットが必要になったときに再開しますか?

いいえ、止まりません。ただし、パイプのもう一方の端を読み取るものが消費するよりも多くの出力を生成し始めると、すぐにブロックされます。つまり、パイプバッファがいっぱいになります。

はいのPIDを取得するにはどうすればよいですか?

良い質問!実行$!直後に含まれているようです。yesただし、中間のサブシェルがあるようで、実際にはそのサブシェルのpidを取得します。<(exec yes violet)中間プロセスを避けるようにしてください。

「アクティブな」fdsのリストを取得できますか?

シェルからではありません。ただし、Linuxのようなオペレーティングシステムを使用している場合は/proc、を参照してください/proc/self/fd

fd4を介したフィルタリングに関する非常に興味深い競合状態、回避できますか?

grepこれを回避するには、スクリプトを続行する前に、プロセスが完了するのを待つ必要があります。そのプロセスのプロセスIDを(上記のように)取得すれば、取得できるはずだと思いますwait

はい、5>&-を実行したときにのみ停止しますか?

はい。次に何が起こるかというと、それはyes永久に出力を生成しようとし続けますが、ファイル記述子のもう一方の端が閉じられると、書き込みエラー( )、またはデフォルトで致命的なEPIPE信号( )が発生します。SIGPIPE

>&-または<&-で閉じるかどうかは重要ですか?

いいえ。一貫性を保つために、両方の構文を使用できます。

于 2013-03-25T08:53:06.140 に答える