什麼時候應該使用輸入重定向?
我使用以下兩個命令來產生相同的結果:-
[root@localhost ~]# grep line comments The line should start with a single quote to comment in VB scripting. Double slashes in the beginning of the line for single line comment in C. [root@localhost ~]# [root@localhost ~]# grep line <comments The line should start with a single quote to comment in VB scripting. Double slashes in the beginning of the line for single line comment in C. [root@localhost ~]#
如果這兩種方法中的任何一種相互比較,任何人都可以向我解釋任何優點/缺點。
從
man grep
頁面(在 Debian 上):描述
grep searches the named input FILEs (or standard input if no files are named, or if a single hyphen-minus (-) is given as file name) for lines containing a match to the given PATTERN. By default, grep prints the matching lines.
在第一種情況下,
grep
打開文件;在第二種情況下,shell 打開文件並將其分配給 的標準輸入grep
,並且grep
沒有傳遞任何文件名參數假定它需要 grep 其標準輸入。優點 1:
grep
可以 grep 多個文件¹。grep
可以顯示每次出現的文件名line
。grep
可以²(但我不知道有任何實現)fadvise(POSIX_FADV_SEQUENTIAL)
對它打開的文件描述符執行 a 。優點 2:
- 如果文件無法打開,shell 將返回一個錯誤,其中將包含更多相關資訊(如腳本中的行號)並且以更一致的方式(如果您讓 shell 也為其他命令打開文件)比何時
grep
打開它。如果文件無法打開,grep
甚至不會被呼叫(這對於某些命令——也許不是grep
——會產生很大的不同)。- in
grep line < in > out
,如果in
無法打開,out
則不會被創建或截斷。- 某些名稱不尋常的文件(例如或以)³
-
開頭的文件名沒有問題。-
- 裝飾性:您可以將
<file
命令行放在任何位置,以更自然地顯示命令流,<in grep line >out
如果您願意的話。- 化妝品:使用 GNU
grep
,您可以選擇在匹配行前面使用的標籤,而不僅僅是文件名,如下所示:<file grep --label='Found in file at line' -Hn line
在性能方面,如果文件無法打開,則
grep
在使用重定向時保存執行,否則grep
我預計不會有太大差異。使用重定向,您不必將額外的參數傳遞給
grep
,您可以使grep
’ 的參數解析稍微容易一些。另一方面,shell 將需要(至少)對文件描述符的額外系統呼叫到dup2()
文件描述符 0。在
{ grep -m1 line; next command; } < file
,grep
(這裡是 GNUgrep
)將想要seek()
回到匹配行之後,以便next command
看到文件的其餘部分(它還需要確定文件是否可搜尋)。換句話說,stdin 中的位置是grep
’s 的另一個輸出。有了grep -m1 line file
,它可以優化它,這是少了一件grep
需要關心的事情。筆記
¹ 使用
zsh
,您可以:grep line < file1 < file2
但這相當於
cat file1 file2 | grep line
(不呼叫cat
實用程序),因此效率較低,如果第一個文件不以換行符結尾並且不會讓您知道在哪個文件中找到該模式,可能會導致混淆。² 即告訴系統
grep
將按順序讀取文件,以便 I/O 調度程序可以做出更有根據的決策,例如如何讀取數據。grep
可以在它自己的fd 上執行此操作,但在它從呼叫者那裡借用的 fd 0 上執行此操作是錯誤的,因為該 fd(或者更確切地說它引用的打開文件描述)可以稍後甚至同時使用用於非順序讀取。³ 在這種情況下
ksh93
,bash
有些文件/dev/tcp/host/port
(以及/dev/fd/x
在某些系統上bash
)在重定向目標中使用時,shell 會出於特殊目的進行攔截,而不是真正打開文件系統上的文件(儘管通常,這些文件文件系統上不存在)。與 所辨識的/dev/stdin
目的相同,但至少,在這裡它的命名空間更合適(任何人都可以在任何目錄中創建一個名為的文件,而只有管理員可以創建一個名為的文件,並且管理員應該更清楚)。-``grep``-``/dev/tcp/host/port