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:
....
答案1
單引號與雙引號版本
讓我們使用單引號定義別名:
$ 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
都會再次進行評估。使用單引號時,命令替換是在執行別名時執行的,而不是在定義別名時執行的。
答案2
如果在定義別名時使用雙引號,則參數擴充發生在別名定義時間。
例如:
$ 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
。
但是,您在這裡也遇到了不同的問題:
設定別名後d='$(date)'
,當您鍵入時,您將獲得在命令列中d
鍵入的文字結果- 該命令將被執行,捕獲輸出,尾隨換行符將被刪除,然後輸出將被解析為命令shell(包括分詞和文件全域擴展)。$(date)
date
由於今天是星期五,因此輸出的第一個單字date
是“Fri”,因此 shell 嘗試將其作為命令運行。
如果你想要的是看輸入的日期d
,只需使用:
alias d=date
或者
alias d='date'
或者
alias d="date"
使用哪種形式並不重要,因為沒有特殊字元需要任何形式的引用。
答案3
正在發生嗎~/.bashrc
?裡面有評論的部分~/.bashrc
95 # Alias definitions.
96 # You may want to put all your additions into a separate file like
97 # ~/.bash_aliases, instead of adding them here directly.
98 # See /usr/share/doc/bash-doc/examples in the bash-doc package.
這就是為什麼我使用另一個建議的文件作為我的快捷方式:
這~/.bash_aliases
關鍵是轉義單引號:
# I use vim but nano or gedit is also fine
vim ~/.bashrc # or vim ~/.bash_aliases
# create your alias:
alias d=''\'date''\'
# or
alias dd="'date'"
# or
alias ddd='"date"'
然後打開一個新的終端機會話並d
執行您想要的操作。