Bash

臨時數據的偽文件

  • September 7, 2020

我經常想將相對較短的字元串數據(儘管可能是幾行)提供給命令行程序,這些程序只接受來自文件(例如 wdiff)的重複輸入。當然,我可以創建一個或多個臨時文件,將字元串保存在那裡並以文件名作為參數執行命令。但在我看來,如果數據實際寫入磁碟,則此過程的效率會非常低,而且如果我多次重複此過程(例如,如果我想輸入單行長文本),它可能會對磁碟造成不必要的傷害文件到 wdiff。有沒有推薦的方法來規避這個問題,比如使用管道等偽文件臨時儲存數據而不實際將其寫入磁碟(或僅在超過臨界長度時才寫入)。請注意, wdiff 接受兩個參數,並且,wdiff <"text".

使用命名管道。舉例說明:

mkfifo fifo
echo -e "hello world\nnext line\nline 3" > fifo

-e告訴 echo 正確解釋換行符 ( ) \n。這將阻塞,即,您的外殼將掛起,直到有東西從管道中讀取數據。

在同一目錄中的某處打開另一個 shell:

cat fifo

您將閱讀迴聲,這將釋放另一個外殼。儘管管道作為文件節點存在於磁碟上,但通過它的數據並不存在;這一切都發生在記憶中。您可以背景 ( &) 迴聲。

管道有一個 64k 的緩衝區(在 linux 上),並且像套接字一樣,當寫滿時會阻塞寫者,所以只要你不過早地殺死寫者,你就不會失去數據。

在 Bash 中,您可以使用command1 <( command0 )重定向語法,它重定向command0的標準輸出並將其傳遞給command1將文件名作為命令行參數的 a。這稱為程序替換

一些採用文件名命令行參數的程序實際上需要一個真正的隨機訪問文件,所以這種技術不適用於那些。但是,它適用於wdiff

user@host:/path$ wdiff <( echo hello; echo hello1 ) <( echo hello; echo hello2 )
hello
[-hello1-]
{+hello2+}

在後台,這會創建一個 FIFO,將 FIFO 中的命令通過管道<( )傳輸到 FIFO,並將 FIFO 的文件描述符作為參數傳遞。要查看發生了什麼,請嘗試使用它echo來列印參數而不用它做任何事情:

user@host:/path$ echo <( echo hello )
/dev/fd/63

創建命名管道更加靈活(如果您想使用多個程序編寫複雜的重定向邏輯),但對於許多目的來說這已經足夠了,而且顯然更易於使用。

>( )當您想將其用作輸出時,還有語法,例如

$ someprogram --logfile >( gzip > out.log.gz )

另請參閱bash 手冊頁“程序替換”部分Bash 重定向備忘單以了解相關技術。

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