Shell-Script
在 Bourne Shell 中讀取多行
我正在嘗試將兩行讀入兩個變數。在 Bash 我會使用這樣的東西:
cat << EOF > myfile line1 line2 EOF cat myfile | { read firstline echo $firstline # "line1" in bash and sh read secondline } echo $firstline # "line1" in bash, empty in sh echo $secondline
然而,在 Bourne Shell 中
$firstline
並且$secondline
在命令組之外是空的。我怎樣才能在sh中做到這一點?
(您很可能
firstline
在 中測試該程式碼時已經設置bash
,它的值最後應該為空)。執行管道時
cat myfile | { read firstline; read secondline; }
右側在子外殼中執行。不是因為,
{ ...; }
而是因為它是管道的一部分。subshell 環境將包含兩個變數firstline
andsecondline
(在兩個變數都被讀取之後),但是當 subshell 終止時將被銷毀,丟棄這兩個變數。這適用於 POSIX
sh
和bash
.在(4.2+) 中,您可以通過設置shell 選項
bash
來解決此問題。lastpipe
從bash
手冊:管道中的每個命令都作為單獨的程序執行(即,在子shell 中)。有關子 shell 環境的描述,請參閱命令執行環境。如果使用內置
lastpipe
啟用該選項 (請參見下面的描述),則管道的最後一個元素可能由 shell 程序執行。shopt``shopt
這將在腳本中起作用,但在啟用了作業控制的互動式 shell 中不起作用(是作業控制使它不起作用,而不是互動性)。
例子:
$ cat script.sh cat << EOF > myfile line1 line2 EOF cat myfile | { read firstline; read secondline; } printf 'first=%s\n' "$firstline" printf 'second=%s\n' "$secondline" shopt -s lastpipe cat myfile | { read firstline; read secondline; } printf 'first=%s\n' "$firstline" printf 'second=%s\n' "$secondline"
$ bash script.sh first= second= first=line1 second=line2
在您的特定情況下,您還可以在 POSIX
sh
和bash
中完全取消和管道,而是直接使用兩個呼叫cat
重定向到復合命令:read
{ read firstline; read secondline; } <myfile
順便說一句,您的機器上很可能沒有真正的歷史 Bourne shell(除非它是 Solaris 11 之前的 Solaris 系統)。我假設您的意思是現代 POSIX
sh
shell。