你能在 shell 使用臨時檔案之前清理它們嗎?

你能在 shell 使用臨時檔案之前清理它們嗎?

如果我的程式崩潰,我想避免出現臨時檔案。

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工具支援它)

這不適用於所有 shell,並且需要作業系統支援 fd 檔案名稱。

答案3

bashshell 中,處理清理的方法是使用trap內建的 EXIT(在bashshell 中鍵入help trap):

trap 'rm temp-file' EXIT

此功能也存在於dashshell 中,sh在現代 Linux 發行版中經常被稱為別名。

相關內容