Bash

如何理解簡單命令的定義?

  • May 3, 2019

從 POSIX 2013 開始:

‘‘simple command’’ 是一系列可選的變數賦值和重定向,以任何順序,可選地後跟單詞和重定向,由控制操作符終止。

來自 Bash 手冊:

簡單命令是最常遇到的命令類型。它只是由空格分隔的單詞,由 shell 的控制運算符之一終止。

我覺得 POSIX 的定義比 Bash 手冊的定義要好。但我仍然不確定 POSIX 的定義:

  • 如果我是正確的,一個簡單命令的終止控制運算符不屬於該命令,或者是嗎?
  • 定義中的兩個“重定向”是否屬於簡單命令?
  • 在“一系列可選的變數分配和重定向”中,“重定向”在變數分配之後做什麼?變數賦值不會寫入標準輸出或標準錯誤,對吧?
  • “一系列可選的變數賦值和重定向,以任何順序”中的“以任何順序”是什麼意思?
  • 該定義為一個簡單的命令建議了多少種可能性,它們是什麼?
  • POSIX 和 Bash 的簡單命令概念是否相同?

添加到格雷格的答案:

  1. 是的,兩組重定向 屬於同一個簡單命令。

當我執行一個輸入(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"三天前")
  1. “以任何順序”指的是我說的最後一件事,也是事實
TZ=GMT0 列=132 ls -l

相當於

列=132 TZ=GMT0 ls -l

(可能會有奇怪的邊緣情況;我們不要在那裡冒險。)

引用自:https://unix.stackexchange.com/questions/271358