如果我的程式崩潰,我想避免出現臨時檔案。
UNIX 的奇妙之處在於您可以讓檔案保持開啟 - 即使在刪除它之後也是如此。
因此,如果您打開該文件,請立即將其刪除,然後然後進行緩慢的處理,即使程式崩潰,用戶也很有可能不必清理檔案。
在 shell 中我常看到類似的東西:
generate-the-file -o the-file
[...loads of other stuff that may use stdout or not...]
do_slow_processing < the-file
rm the-file
但如果程式崩潰之前rm
用戶就必須進行清理the-file
。
在 Perl 中你可以這樣做:
open(my $filehandle, "<", "the-file") || die;
unlink("the-file");
while(<$filehandle>) {
# Do slow processing stuff here
print;
}
close $filehandle;
然後文件一打開就會被刪除。
shell中有類似的構造嗎?
答案1
這在 csh、tcsh、sh、ksh、zsh、bash、ash、sash 中進行了測試:
echo foo > the-file
(rm the-file; cat) < the-file | do_slow_processing
do_other_stuff
或者如果您願意:
(rm the-file; do_slow_processing) < the-file
do_other_stuff
有趣的是,它也適用於 fifo:
mkfifo the-fifo
(rm the-fifo; cat) < the-fifo | do_slow_processing &
echo foo > the-fifo
這是因為在寫入內容之前,讀者會被阻塞。
答案2
generate-the-file > the-file
exec 5< the-file
rm the-file
...
do_slow_processing 0<&5
筆記:
- 您需要在沒有可執行檔的情況下執行 exec,因此它會影響 shell 本身的描述符
- 最多僅提供 9 個 fd
- 如果需要檔名,可以使用 /proc/self/fd/X 。此介面不可在 UNIX 風格之間移植(不過它可能適合您)。
- 嘗試再次讀取 fd(例如兩次呼叫
cat 0<&5
)將會失敗,因為您處於 EOF 位置。您需要倒帶它,或透過閱讀來克服它/proc/self/fd/X
- 在上面的大多數情況下,您可以在沒有實際文件的情況下進行操作,但可以執行一個簡單的操作
generate-the-file | do_slow_processing
更新:
OP 提到generate-the-file
可能不會在標準輸出中產生輸出。對此有一些習慣用語:
- 指定輸出文件
-
.通常接受輸出檔名 - 表示 stdout。這是經 POSIX.1-2017 認可:準則 13: 對於使用操作數來表示要打開以進行讀取或寫入的文件的實用程序,“-”操作數應僅用於表示標準輸入(或標準輸出,當從上下文中清楚地看出正在指定輸出文件時)或檔案名稱為-.
(對於那些明確定義的實用程式之外的實用程序,它是實現定義的,但很有可能您的generate-the-file
工具支援它)
使用
/dev/stdout
或/proc/self/fd/1
.取決於作業系統,請參閱/dev/stdin、/dev/stdout 和 /dev/stderr 的可攜性如何?使用進程替換。 bash 將允許您寫入
>(process substitution)
檔案名稱。例如:wget -O >(rot13 > Question.txt)https://unix.stackexchange.com/q/579535/70346
這不適用於所有 shell,並且需要作業系統支援 fd 檔案名稱。
答案3
在bash
shell 中,處理清理的方法是使用trap
內建的 EXIT(在bash
shell 中鍵入help trap
):
trap 'rm temp-file' EXIT
此功能也存在於dash
shell 中,sh
在現代 Linux 發行版中經常被稱為別名。