從標準輸入創建臨時文件
假設我有一個文件內容的標準輸入流和一個需要文件名作為參數的命令,並且我想在由標準輸入流的文件內容組成的文件上執行該命令。
例如,而不是命令
imageviewer mouse.jpg
我想要一些神奇的線條
magic
,使它相當於cat mouse.jpg | magic
這在or
magic
中會是什麼樣子?zsh``bash
最好是,我希望它看起來像
cat mouse.jpg | submagic | xargs imageviewer
也就是說,我想
submagic
從標準輸入流創建一個臨時文件並輸出創建的文件的文件名。這些行
magic
或submagic
應該是僅使用 bash 或 zsh 命令、它們的內置命令、GNU coreutils 等的 shell 管道。這是整個問題。以下只是澄清和背景,因為人們一直誤解我的意思。
好的,所以我以為我說清楚了,但似乎我沒有說清楚:我真的希望有一個管道相當於
imageviewer mouse.jpg
正是從 .開始的
cat mouse.jpg | …
。也就是說,我真的想要一條線或這樣一條線,這樣上面的管道就可以正常工作了——我的意思是我的問題。magic``submagic
這尤其意味著以下建議的解決方案不起作用:
- 開始管道
tmpfile = $(mktemp); cat mouse.jpg | …
- 將其重寫為
imageviewer =(cat mouse.jpg)
- 將其重寫為
echo mouse.jpg | xargs imageviewer
- 使用函式或二進製文件來解決它,比如通過定義
function magic () { … }
可以說,我感興趣的是是否可以編寫別名
alias magic='…'
,或者是否可以編寫alias submagic='…'
上述管道之一,並且這些別名的定義僅包含 bash 或 zsh 命令、GNU coreutils 等 -沒有什麼自己寫的。另一個評論。你認為
imageviewer
是feh
或sxiv
或某事。背景。當我嘗試使用我的郵件客戶端打開幾個附加到郵件的圖像文件時,我想到了這個問題
neomutt
。Neomutt 提供標記附加文件,然後將文件內容通過管道傳輸到您可以輸入的命令行。所以在這裡,我只能給出一個命令行,它在給定的標準輸入流上執行某些操作。這就是問題的來源。但我對原始問題不感興趣,而只對這個問題感興趣。
bash
至少,使用過程替換:utility <( some_other_utility )
這將顯示
utility
一個文件名。當utility
打開文件並從中讀取時,它將讀取some_other_utility
.你的例子:
cat mouse.jpg | submagic | xargs imageviewer
我假設這是為了將文件名
mouse.jpg
發送到imageviewer
,因為通過xargs
.這可以通過
echo 'mouse.jpg' | xargs imageviewer
或者
xargs imageviewer <<<'mouse.jpg'
在
bash
.發送 to 的內容
mouse.jpg
可以imageviewer
用cat mouse.jpg | imageviewer /dev/stdin
或者,使用過程替換,與
imageviewer <( cat mouse.jpg )
使用臨時文件:
tmpfile=$(mktemp) cat mouse.jpg >"$tmpfile" imageviewer "$tmpfile" rm "$tmpfile"
可能,
tmpfile=$(mktemp) cat mouse.jpg | { cat >"$tmpfile"; echo "$tmpfile"; } | xargs imageviewer rm "$tmpfile"
xargs
該管道依賴於等待執行的事實,imageviewer
直到它從管道的中間部分讀取文件名。在創建臨時文件之前,中間命令不會輸出文件名。
在澄清
submagic
問題後,我編輯了答案。在
zsh
您可以使用命令的輸出創建一個臨時文件=( ... )
。與之相反<( ... )
,可以使用設備文件/dev/fd...
或命名管道,表單=( ... )
創建可查找的臨時文件。請參閱http://zsh.sourceforge.net/Doc/Release/Expansion.html#Process-Substitution假設這
cat mouse.jpg
只是將圖像數據發送到標準輸出的任何命令的範例,您可以使用imageviewer =(cat mouse.jpg)
如果您需要 zsh 創建的臨時文件具有特定的副檔名,您可以設置
TMPSUFFIX
特殊變數):(TMPSUFFIX=.jpg; imageviewer =(cat mouse.jpg))
第二次更新
如果你堅持語法
cat mouse.jpg | submagic | xargs imageviewer
可以創建一個
submagic
類似於 Kusalananda 回答中已經提出的命令的腳本。#! /bin/sh # A fixed name allows multiple runs without creating lots of files and # allows a simple script to remove the file afterwards. TMPFILE=/tmp/submagic.tmp.jpg rm -f "$TMPFILE" && cat > "$TMPFILE" && echo "$TMPFILE"
與這樣的 shell 機制相反,執行後
=( cat mouse.jpg )
不會刪除。$TMPFILE``imageviewer
如果您可以在執行後執行第二個腳本,
imageviewer
如果它知道名稱,則可以刪除該文件。腳本
submagic-cleanup
#! /bin/sh # A fixed name allows a simple script for cleaning up. TMPFILE=/tmp/submagic.tmp.jpg rm -f "$TMPFILE"
然後你可以執行
cat mouse.jpg | submagic | xargs imageviewer submagic-cleanup