Io-Redirection
為什麼 echo > 1 2 3 會創建一個名為 1 且內容為 2 3 的文件?
$ echo > 1 2 3; ls -latr 1; cat 1 -rw-rw-r-- 1 kahn kahn 4 Jun 23 14:05 1 2 3
這與
>
重定向的評估有關嗎?這樣:echo > 1 2 3
在技術上也可以重寫為:
echo 2 3 > 1
?
是否有任何資源可以更好地理解 IO 重定向的操作順序以及如何評估它?我承認這個例子可能不是很有用,甚至不會經常發生,但我想更好地了解這裡到底發生了什麼。
您可以參考的適當資源是 POSIX shell 語法,它定義了一個簡單的命令:
simple_command : cmd_prefix cmd_word cmd_suffix | cmd_prefix cmd_word | cmd_prefix | cmd_name cmd_suffix | cmd_name ;
這裡最相關的部分是 的定義
command_suffix
:cmd_suffix : io_redirect | cmd_suffix io_redirect | WORD | cmd_suffix WORD ;
這是遞歸的,允許重定向和命令參數以任何順序出現。
此外,POSIX 將重定向的語法定義為
[n]redir-op word
雖然可選數字
n
和重定向運算符(>
在您的情況下為 )之間不允許有空格,但在重定向運算符和以下單詞之間允許有任意數量的空格。擴展後,word
(1
,在您的情況下) 用作流被定向到(或來自)的文件的名稱。因此,寫成同樣合法
$ echo > 1 foo bar # ^^^^ ^^^^^^^^^^^^^ # \ \ # \ cmd_suffix # \ ^^^ ^^^ ^^^ # \ \ \ \ # \ \ \ WORD # \ \ WORD # \ io_redirect # cmd_name
或者
$ echo foo >1 bar
甚至
$ echo > 1 foo > 1 bar > 1
(當然,重複
> 1
沒有任何意義)。為了完整起見:
cmd_prefix
定義中simple_command
的 本身是遞歸定義的:cmd_prefix : io_redirect | cmd_prefix io_redirect | ASSIGNMENT_WORD | cmd_prefix ASSIGNMENT_WORD ;
這意味著重定向和變數賦值可以以任何順序出現在命令之前。
然後,您可能有,例如,
$ LC_ALL=C <infile sort >outfile 2>errfile # ^^^^^^^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^ # \ \ \ # cmd_prefix cmd_word cmd_suffix
或者
$ 2>errfile >outfile <infile LC_ALL=C sort
或者
$ LC_ALL=C sort <infile 2>errfile >outfile
這都是同樣合法的,但必須記住,重定向和變數賦值以及擴展是從左到右執行的,並且它們的順序可能是相關的(例如,如果
infile
不存在,則outfile
不會被截斷)cat <infile >outfile
位於cat >outfile <infile
)。