
想像我目前的工作目錄中有兩個資料夾:back/
和front/
。我試圖進入他們每個人的內心並做一些事情。從下面的簡單腳本:
for dir in */ ; do
echo "$(dir)"
done
我期待這樣的輸出:
back
front
然而,我得到的是:
back front
back front
我不明白。結果是,如果我嘗試cd
進入該資料夾:
for dir in */ ; do
echo "$(dir)"
cd $(dir)
echo "$(pwd)"
cd ..
done
我得到:
back front
/path/to/back
back front
/path/to/back
即我從不進入front/
。有人可以幫助我理解我做錯了什麼嗎?
答案1
在類似 POSIX 的 shell 中,$(cmd)
語法是命令替換,擴展為減去尾隨換行符$(cmd)
的輸出。cmd
你想要的是參數擴充:$dir
或${dir}
(此處參數為dir
多變的)。
pwd
( p
rint w
orking d
ictory) 是輸出 1 特殊變數內容的命令,$PWD
該變數本身包含目前工作目錄的路徑,因此只要不以換行符號結尾,$(pwd)
就會擴展為相同的內容。$PWD
$PWD
所以你要:
for dir in */; do
(
printf '%s\n' "$dir"
cd -- "$dir" &&
printf '%s\n' "$PWD"
)
done
或者:
for dir in */; do
(
printf '%s\n' "$dir"
cd -- "$dir" &&
pwd
)
done
也請記住
echo
不能用於輸出任意數據,請printf
改為使用- 您通常應該檢查命令的退出狀態。這裡不檢查 的輸出
cd
意味著cd ..
如果第一個失敗,接下來的操作會將您帶到錯誤的位置cd
。 cd
最好在子 shell 中執行(使用(...)
)而不是使用,cd ..
因為後者並不總是保證讓您回到初始位置(如果涉及符號連結和/或某些路徑組件已在間隔中重新命名)--
當不能保證非選項不以開頭-
(或+
對於某些命令來說也可能是一個問題)時,必須使用 來將選項與非選項分開。- 在類似 POSIX 的 shell 中,參數擴展和命令替換(以及算術擴展)必須用引號引起來,否則它們會經歷您通常不希望的隱式 split+glob(zsh 除外)。
另請注意,在 bash(以及 zsh 以外的其他 POSIX shell)中,當 glob 與任何檔案都不匹配時,它不會展開。
因此如果當前工作目錄不包含任何可以確定為類型的非隱藏文件目錄,*/
全域模式將擴展到自身*/
而不是空列表,您可能會看到一個錯誤,因為cd
它無法進入該*/
目錄。
在 中zsh
,您可以使用N
glob 限定詞for dir in */(N); do...
(或for dir in *(N-/); do...
避免$dir
以 結尾/
)。
在 ksh93 中:for dir in ~(N)*/; do...
.
在 中bash
,您可以nullglob
暫時全域設定該選項:
shopt -s nullglob
for dir in */; do
...
done
shopt -u nullglob
為了完整起見,$(var)
語法為宏Makefile
命令使用的 s中的擴充make
。
在該awk
語言中,$
是取消引用欄位的一元運算符,您只需用來var
引用awk
變數。因此,將與or$(var)
相同並擴展到第th字段(如果為 0,則擴展到整個記錄)。$var
$ var
var
var
在rc
-like shell 中,與, , ,$(var)
相同也可以工作,因為這是傳遞給 的一個元素的列表,因此您取消引用該變量,儘管您通常只使用.$var
$ var
$ 'var'
$ ( 'var' )
$
var
$var
在 TCL 中,$(var)
將擴展為鍵名稱為空的數組變數的值var
:
$ tclsh
% array set {} {foo 1 bar 2}
% puts $(foo)
1
是的,如果在這種情況下, P
rintP
就沒有多大意義。你可以猜到pwd
命令(來自 70 年代中期的 Unix V5)是第一個,$PWD
並且邏輯的POSIX 指定的當前工作目錄的處理是後來出現的(在 80 年代初的 ksh 中,其中實際上是(是的,缺少和引號!)pwd
的別名,並且在文檔中被縮寫為resent orking目錄)。有一個(當前orking目錄)變數用於相同目的print - $PWD
-r
$PWD
P
W
D
tcsh
$cwd
c
w
d