使用命名管道
有時你可能希望通過一個程式輸出內容並將其輸入另一個程式,但不能使用標準管道。
ls -l | grep ".log"
你可以簡單地寫一個臨時檔案:
touch tempFile.txt
ls -l > tempFile.txt
grep ".log" < tempFile.txt
這適用於大多數應用程式,但是,沒有人會知道 tempFile
做了什麼,如果它包含該目錄中 ls -l
的輸出,有人可能會刪除它。這是命名管道發揮作用的地方:
mkfifo myPipe
ls -l > myPipe
grep ".log" < myPipe
myPipe
在技術上是一個檔案(一切都在 Linux 中),所以讓我們在我們剛剛建立管道的空目錄中執行 ls -l
:
mkdir pipeFolder
cd pipeFolder
mkfifo myPipe
ls -l
輸出是:
prw-r--r-- 1 root root 0 Jul 25 11:20 myPipe
注意許可權中的第一個字元,它被列為管道而不是檔案。
現在讓我們做一些很酷的事情。
開啟一個終端,記下目錄(或建立一個目錄,以便清理很容易),並製作一個管道。
mkfifo myPipe
現在讓我們把東西放進菸斗裡。
echo "Hello from the other side" > myPipe
你會注意到這個懸掛,管道的另一側仍然關閉。讓我們開啟管道的另一邊,然後讓這些東西通過。
開啟另一個終端並轉到管道所在的目錄(或者如果你知道它,則將其新增到管道中):
cat < myPipe
你會注意到,輸出 hello from the other side
後,第一個終端中的程式結束,第二個終端中的程式也就完成了。
現在反向執行命令。從 cat < myPipe
開始,然後回覆一些東西。它仍然有效,因為程式會等到一些東西放入管道才終止,因為它知道它必須得到一些東西。
命名管道可用於在終端之間或程式之間移動資訊。
管道很小。一旦完整,寫入器就會阻塞,直到某些讀取器讀取內容,因此你需要在不同的終端中執行讀取器和寫入器,或者在後臺執行一個或另一個:
ls -l /tmp > myPipe &
cat < myPipe
使用命名管道的更多示例:
-
示例 1 - 同一終端/同一 shell 上的所有命令
$ { ls -l && cat file3; } >mypipe & $ cat <mypipe # Output: Prints ls -l data and then prints file3 contents on screen
-
示例 2 - 同一終端/同一 shell 上的所有命令
$ ls -l >mypipe & $ cat file3 >mypipe & $ cat <mypipe #Output: This prints on screen the contents of mypipe.
注意顯示
file3
的第一個內容然後顯示ls -l
資料(LIFO 配置)。 -
示例 3 - 同一終端/同一 shell 上的所有命令
$ { pipedata=$(<mypipe) && echo "$pipedata"; } & $ ls >mypipe # Output: Prints the output of ls directly on screen
請注意,變數
$pipedata
不能在主終端/主 shell 中使用,因為使用&
會呼叫子 shell,而$pipedata
僅在此子 shell 中可用。 -
示例 4 - 同一終端/同一 shell 上的所有命令
$ export pipedata $ pipedata=$(<mypipe) & $ ls -l *.sh >mypipe $ echo "$pipedata" #Output : Prints correctly the contents of mypipe
由於變數的匯出宣告,這會在主 shell 中正確列印
$pipedata
變數的值。由於呼叫背景 shell(&
),主終端/主 shell 沒有掛起。