Shell

timetimecd 實際上是做什麼的?(shell 中的反斜杠很有趣)

  • March 15, 2016

/usr/bin/time在討論與 shell(bash 和 zsh) built-in之間的區別時time,有人提到可以將\time其用作 get 的簡寫/usr/bin/time

首先,這似乎是一個不錯的天真的捷徑,但隨後出現了一些問題:

  • 為什麼也t\ime有效?
  • 為什麼要\cd更改目錄,即使/usr/bin/cd¹ 沒有?

所以很明顯,\foo不等價於$(which foo)。現在的問題是:

在 bash 和 zsh 中觀察到的行為是否\foo以任何方式包含在 shell 的 POSIX 定義中,如果是,為什麼它的行為如此?


腳註 1:/usr/bin/cd是,在我的系統上,

#!/bin/sh
builtin cd "$@"

t\imeor \cd(或"tim"eor 'cd'or or ${-##*}timeor${-+time}以及您能想到的所有其他引用和擴展組合最終將解析為timeor cd),是:另一種編寫方式cdand time

但是,這最終會在 shell 語法解析和解釋時cd或之後解決。time特別是,在 shell 關鍵字辨識和別名替換發生很久之後就會發生這種情況。

因此,當 shell 在其語言中尋找關鍵字時,它並沒有辨識ti\metimeshell 關鍵字。所以一個:

ti\me echo test

將被 shell 辨識為一個簡單的命令,而不是time關鍵字後跟一個簡單的命令。

然後引用 inti\me將被處理(這裡反斜杠引用了m無論如何都不需要引用的字元,引用字元被刪除,你得到time)並且將像任何其他命令一樣查找命令(在內置命令列表time ,函式和執行檔$PATH。很可能會在/bin/time這裡)

對於cd,shell 語言中沒有cd關鍵字,只有一個cd內置命令(優先於您的/usr/bin/cd)。但是,如果您確實為cd(like alias cd=pushd) 定義了別名,則同樣如此。由於別名替換很早就完成了,在刪除引號之前,如果你有一個別名 forcd而不是一個 for \cd(請注意,沒有多少 shell 允許其中包含反斜杠的別名),然後編寫:

\cd dir

你確保你的cd別名沒有被替換。

簡而言之,引用命令名稱或其任何部分可防止其被視為 shell 關鍵字(關鍵字如while, for, if, {…僅time某些shell 中是關鍵字),並繞過您可能擁有的別名.

但是,它不會強制該命令解析為 in 中的執行檔$PATH,該命令仍會首先在函式(您可以通過 do 解決command time cmd...)和內置函式(您可以通過 do 解決env time cmd...,儘管我不知道具有內置time命令的外殼)。

請注意,在某些 shell 中,引用也可能對typeset/ declare/ export/ … 系列的特殊內置函式的行為產生影響。local請參閱局部變數賦值是否需要引號?詳情。

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