Bash

為什麼在使用管道時必須將讀取的命令放入子shell

  • December 1, 2020

該命令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")是一個子shell,但我不知道為什麼我必須在這裡製作一個子shell。據我了解,x|y會將 的輸出重定向x到 的輸入y。為什麼read a; read a b; echo $a無法獲得輸入但子shell可以?

這裡的主要問題是正確地對命令進行分組。子殼是次要問題。

x|y將輸出重定向x到輸入y

是的,但x | y; z不會將 的輸出重定向xyz

df . | read a; read a b; echo "$a"中,管道僅連接df .read a,其他命令與該管道沒有連接。您必須將reads 組合在一起:df . | { read a; read a b; }df . | (read a; read a b)將管道連接到它們。

但是,現在出現了子shell 問題:管道中的命令在子shell 中執行,因此在其中設置變數不會影響父shell。因此該echo命令必須與reads 位於相同的子 shell 中。所以:df . | { read a; read a b; echo "$a"; }

現在無論您在這裡使用( ... )還是{ ...; }沒有特別的區別,因為管道中的命令無論如何都是在子shell中執行的。

引用自:https://unix.stackexchange.com/questions/622296