Bash
別名的單引號內的命令替換
bash 中需要雙引號來進行命令替換:
$ echo "$(date)" Fri Oct 28 19:16:40 EDT 2016
而單引號不做命令替換:
$ echo '$(date)' $(date)
…為什麼我會看到以下行為
alias
似乎表明命令替換是用單引號發生的?alias d='$(date)' $ d No command 'Fri' found, did you mean: ....
單引號與雙引號版本
讓我們使用單引號定義別名:
$ alias d='$(date)'
現在,讓我們檢索別名的定義:
$ alias d alias d='$(date)'
觀察到尚未執行命令替換。
讓我們做同樣的事情,但這次使用雙引號:
$ alias d="$(date)" $ alias d alias d='Fri Oct 28 17:01:12 PDT 2016'
因為使用了雙引號,所以在定義別名之前執行了命令替換。
單引號版本
讓我們嘗試執行單引號版本:
$ alias d='$(date)' $ d bash: Fri: command not found
單引號版本相當於執行:
$ $(date) bash: Fri: command not found
在這兩種情況下,執行命令時都會執行命令替換。
變種
讓我們考慮這個使用命令替換並使用單引號定義的別名:
$ alias e='echo $(date)' $ e Fri Oct 28 17:05:29 PDT 2016 $ e Fri Oct 28 17:05:35 PDT 2016
每次我們執行此命令時,
date
都會再次評估。使用單引號,命令替換是在執行別名時執行的,而不是在定義別名時執行的。
如果在定義別名時使用雙引號,則參數擴展發生在別名定義時。
例如:
$ pwd /tmp $ echo $PWD /tmp $ alias p="echo $PWD" $ p /tmp $ cd / $ pwd / $ p /tmp $ alias p alias p='echo /tmp' $
如果您希望在呼叫別名時發生參數擴展,請在定義別名時使用單引號:
$ alias p='echo $PWD' $ p /tmp $ cd / $ p / $
當然,沒有任何理由執行該命令~~
echo "$(date)"
~~。我知道您只是將其用作範例,但是由於我已經多次“在野外”看到這種情況,所以無論如何我都會澄清一下:這意味著,執行date
命令並擷取輸出(去掉任何尾隨的換行符)。然後將擷取的輸出作為參數傳遞給echo
命令,該命令將列印它,以及一個尾隨換行符。與直接執行相比沒有任何優勢date
。但是,您在這裡也遇到了不同的問題:
當你設置 alias
d='$(date)'
時,當你輸入時,你會得到在命令行d
輸入的文字結果——命令將被執行,輸出被擷取,尾隨換行符將被剝離,然後輸出將被解析為命令shell(包括分詞和文件全域擴展)。$(date)``date
由於是星期五,輸出的第一個單詞
date
是“Fri”,因此 shell 嘗試將其作為命令執行。如果您想要在鍵入時查看
d
日期,只需使用:alias d=date
或者
alias d='date'
或者
alias d="date"
您使用哪種形式並不重要,因為沒有特殊字元需要任何形式的引用。