パイプを使用するときに読み取りコマンドをサブシェルに入れるのはなぜですか?

パイプを使用するときに読み取りコマンドをサブシェルに入れるのはなぜですか?

このコマンドは、df .現在使用中のデバイスを表示します。例えば、

me@ubuntu1804:~$ df .
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sdb1       61664044 8510340  49991644  15% /home

今、文字列を取得したいと思います/dev/sdb1

これを試しましたが、うまくいきません。df . | read a; read a b; echo "$a"このコマンドは空の出力を提供します。しかし、df . | (read a; read a b; echo "$a")期待どおりに動作します。

今は少し混乱しています。

これがサブシェルであることはわかりますが、(read a; read a b; echo "$a")なぜここでサブシェルを作成するのかわかりません。私が理解しているところによると、の出力はの入力にx|yリダイレクトされます。なぜ私は入力を受け取ることができませんが、サブシェルでは入力を受け取ることができますか?xyread a; read a b; echo $a

ベストアンサー1

ここで最も重要な問題は、コマンドを正しくグループ化することです。サブシェルはマイナーな問題です。

x|yx出力を入力にリダイレクトy

はい、しかし、出力をからまたはにx | y; zリダイレクトしません。xyz

ではdf . | read a; read a b; echo "$a"、パイプは接続のみになり、df .他のread aコマンドはこのパイプと接続されません。readそれらを一緒にグループ化するdf . | { read a; read a b; }か、df . | (read a; read a b)パイプを接続する必要があります。

しかし、現在サブシェルの問題が発生しました。パイプラインのコマンドはサブシェルで実行されるため、サブシェルに変数を設定しても親シェルには影響しません。したがって、このechoコマンドはreadsと同じサブシェルになければなりません。だから:df . | { read a; read a b; echo "$a"; }

パイプのコマンドはとにかくサブシェルで実行されるため、使用するかどうか( ... )に特別な違いはありません。{ ...; }

おすすめ記事