[英]Difference between “open function” and “touch command” in Perl?
以下兩種文件創建情況有什么區別。
open(DATA,">newfile.txt"); #1.using open function
close(DATA);
`touch newfile.txt`; #2.using touch command
哪個更好更快? 注意:當 Perl 腳本中同時使用 open 函數和 touch 命令時,考慮它用於創建空文件。
明顯的區別在於,在第二種情況下,您將進入系統。 啟動一個 shell 來運行命令或命令通過execvp
系統調用運行(取決於參數,見下文)。 有很多事情正在發生,很多事情也可能出錯。
更重要的是,還有很多事情要做。 如果文件已經存在怎么辦? 一方面, open
會截斷它,而touch
只會更新時間戳。 但是您想要一個新文件,因此無論如何您都需要先檢查。 如果這失敗了怎么辦? 你需要檢查一下。 因此,這應該是一個小程序。
然后只需用 Perl 編寫所有內容。 委派這么簡單的工作沒有任何好處,只有陷阱。
注意:使用三參數open
open my $fh, '>', $file or ...
進行所有必要的檢查。 然后,您還有一個更好的詞法(間接)文件句柄可以使用。
感謝hek2mgi的評論和ikegami澄清qx可能會根據參數繞過 shell(什么似乎沒有記錄?),就像系統一樣。
這可以根據hek2mgi注釋通過strace -f script.pl
進行檢查,其中在腳本中使用qx(touch "NEW")
可以找到該行
[pid 24332] execve("/bin/sh", ["sh", "-c", "touch \"NEWFILE\""], [/* ...
而qx(touch NEW)
的輸出中沒有/bin/sh
(沒有引號,沒有外殼)。
需要注意的是, qx
確實接受一個數組(在文檔中未提及),它顯然是內插的。 這可以從strace -f
on qx(@cmd)
with @cmd = qw(ls -l > tt.out)
輸出中看出,它具有
[pid 30773] execve("/bin/sh", ["sh", "-c", "ls -l > tt.out"], [/* ...
然后,如果需要(此示例)而不是其他情況( qw(ls -l
)),則 shell 會運行,如上所述。
*哪個更好更快?
這個問題沒有意義。 這兩個片段並不等效,因此您應該問“其中哪一個可以滿足我的要求?” 如果文件存在,則open
將破壞文件,而touch
將保持不變。
至於使用系統調用與外殼運行外部命令哪個更好,如果您不遺漏問題中的大部分代碼,答案是顯而易見的!
直接使用系統調用:
utime(undef, undef, $qfn)
or die("Can't touch \"$qfn\": $!\n");
通過外部命令使用系統調用:
use String::ShellQuote qw( shell_quote );
my $cmd = shell_quote("touch", "--", $qfn);
my $output = `$cmd 2>&1`;
die("Can't touch \"$qfn\": Killed by signal ".($? & 0x7F)."\n" if $? & 0x7F;
die("Can't touch \"$qfn\": Exited with error ".($? >> 8).": $output" if $? >> 8;
如您所見,炮擊要復雜得多,而且容易出錯。 當然,啟動整個程序來進行系統調用而不是僅僅進行系統調用要慢得多。
它們是兩個非常不同的命令。
touch
用於修改文件的訪問和修改時間。 默認情況下,它將訪問和修改時間設置為當前時間,如果文件不存在 - 它會將其創建為一個空文件。
open
用於打開文件以進行讀取或寫入。 根據給定的模式,如果文件不存在, open 命令也可以創建文件。
使用touch
意味着調用一個單獨的進程(一個 shell),因此考慮到這個限制, open
API 命令是首選。
open
: 用於讀/寫。
touch
: 用於更新/修改。
但是, touch
通過實際克隆自身(perl 克隆)來運行另一個進程來打開一個 shell。
Open 函數用於讀/寫文件。 該函數使用文件描述符,然后寫入指定的文件。 而觸摸功能會創建一個新文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.