如何理解簡單命令的定義?
從 POSIX 2013 開始:
‘‘simple command’’ 是一系列可選的變數賦值和重定向,以任何順序,可選地後跟單詞和重定向,由控制操作符終止。
來自 Bash 手冊:
簡單命令是最常遇到的命令類型。它只是由空格分隔的單詞,由 shell 的控制運算符之一終止。
我覺得 POSIX 的定義比 Bash 手冊的定義要好。但我仍然不確定 POSIX 的定義:
- 如果我是正確的,一個簡單命令的終止控制運算符不屬於該命令,或者是嗎?
- 定義中的兩個“重定向”是否屬於簡單命令?
- 在“一系列可選的變數分配和重定向”中,“重定向”在變數分配之後做什麼?變數賦值不會寫入標準輸出或標準錯誤,對吧?
- “一系列可選的變數賦值和重定向,以任何順序”中的“以任何順序”是什麼意思?
- 該定義為一個簡單的命令建議了多少種可能性,它們是什麼?
- POSIX 和 Bash 的簡單命令概念是否相同?
添加到格雷格的答案:
- 是的,兩組重定向 屬於同一個簡單命令。
當我執行一個輸入(stdin)和輸出(stdout)重定向的命令時,我這樣做:
*cmd 參數1 參數2* <*文件*1 >*文件2*
一些人(少數人)主張
<文件 1 *cmd 參數1 參數2* >*文件2*
變化,因為他們認為指定輸入,然後是動作,然後是輸出更直覺。但以下都是等價的:
<*文件*1 >文件 2 *cmd 參數1 參數2*
>文件 2 *cmd 參數1 參數2* <*文件1*
*cmd* >文件 2*參數1* <*文件 1 參數2*
不要使用上述任何一種;它們被作為不好的例子提出。
關鍵是重定向可以出現在命令的第一個單詞(或命令中的任何單詞)之前或之後,但它們的處理方式相同。 3. 變數賦值可能在命令之前,設置環境變數僅用於該命令的持續時間(範圍)。例如,
TZ=GMT0 ls -l
列出您的文件,以格林威治標準時間顯示修改時間。“任意順序的可選變數分配和重定向”意味著
TZ=GMT0 ls -l > ls_output_file
TZ=GMT0 > ls_output_file ls -l
> ls_output_file TZ=GMT0 ls -l
都是等價的。同樣,除了第一個之外,不要使用任何這些。
關鍵是變數賦值不能出現在命令的第一個單詞之後;如果這樣做,它們將被視為命令的參數。例如,查看
dd
.變數賦值不會寫入標準輸出或標準錯誤,對吧?
簡單、恆定的數據分配不做任何處理(shell 內的簿記不計算在內)。但是命令替換執行一個命令;
CURRENT_DATE=$(date +%Y%m%d)
執行命令date +%Y%m%d
,並將其標準輸出重定向到外殼的管道,外殼擷取輸出並將其嵌入到命令行中。但是date
命令的stderr還是shell的stderr;如果您說OLD_DATE=$(date --date"three days ago")
,您將在螢幕上收到一條錯誤消息,因為date
不支持該語法來指定日期。當然,如果你說,你可以壓制它OLD_DATE=$(date --date"三天前" 2> /dev/null)
但如果你說
OLD_DATE=$(date --date"三天前") 2> /dev/null
或者
2> /dev/null OLD_DATE=$(date --date"三天前")
- “以任何順序”指的是我說的最後一件事,也是事實
TZ=GMT0 列=132 ls -l
相當於
列=132 TZ=GMT0 ls -l
(可能會有奇怪的邊緣情況;我們不要在那裡冒險。)