單引號內的指令替換別名

單引號內的指令替換別名

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執行您想要的操作。

相關內容