Bash
為什麼在使用管道時必須將讀取的命令放入子shell
該命令
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
不會將 的輸出重定向x
到y
和z
。在
df . | read a; read a b; echo "$a"
中,管道僅連接df .
和read a
,其他命令與該管道沒有連接。您必須將read
s 組合在一起:df . | { read a; read a b; }
或df . | (read a; read a b)
將管道連接到它們。但是,現在出現了子shell 問題:管道中的命令在子shell 中執行,因此在其中設置變數不會影響父shell。因此該
echo
命令必須與read
s 位於相同的子 shell 中。所以:df . | { read a; read a b; echo "$a"; }
。現在無論您在這裡使用
( ... )
還是{ ...; }
沒有特別的區別,因為管道中的命令無論如何都是在子shell中執行的。