為什麼 cd 命令處理 STDIN 與其他命令不同?
像這樣的命令
cd
不能將輸出通過管道傳輸給它們以更改目錄——它們需要命令行參數。為什麼該
cd
命令(以及與它類似的命令,例如mv
,cp
, &rm
)在讀入時不像大多數其他命令那樣起作用STDIN
?阻止它讀取標準輸入以更改目錄的邏輯是什麼?我能找到的最佳答案是:
cd 不是外部命令 - 它是一個 shell 內置函式。它在目前 shell 的上下文中執行,而不是像外部命令那樣,在 fork/exec 的上下文中作為單獨的程序執行。
但是,對我來說,上面的答案根本沒有真正解釋它:為什麼
cd
處理STDIN
與讀入的許多其他命令不同STDIN
?
讀取的命令
stdin
幾乎是所有過濾器系列,即將文本數據流轉換為已轉換數據流的程序。
cat
,sed
,awk
,gzip
甚至sh
是這種“過濾器”的好例子。引用的命令和絕對不是過濾器,而是使用傳遞的參數(此處為文件或目錄)執行操作的命令
cp
。mv``rm
該
cd
命令與它們類似,它需要一個參數(如果未提供,則模擬預設參數),並且通常不會在 上輸出任何內容stdout
,儘管在某些情況下(例如使用CDPATH
.即使想要創建一個
cd
從標準輸入獲取目標目錄的變體,在 Bourne shell 中的管道中使用它也不會產生任何影響,dash
僅舉bash
幾例。該命令的最後一個組件在子 shell 中執行,對新目錄的更改不會影響目前 shell。例如:echo /tmp | cd
可以使用ksh93
但不能使用bash
,dash
,zsh
,sh
, …
cd <(echo /tmp)
可以與支持程序替換的 shell 一起使用(至少ksh
,bash
,zsh
),但與cd $(echo tmp)
唯一可能感興趣的案例是:
echo tmp | (cd ; pwd)
最後,這樣的變體需要解決以下情況:它沒有給出參數但預期的行為是將目錄更改為使用者的主目錄,或者沒有給出參數但預期的行為是從中讀取目標目錄的名稱標準輸入。由於沒有可靠的方法來決定,這是注定的。