2 回答

TA貢獻883條經驗 獲得超454個贊
for 語句中的 in 后面的內容就是需要被循環的哪些項。 比如?for i in A B C 在循環時,i 就分別是 A、B、C 這三個單詞。
你理解這個 for 循環里的 i 是要在哪些項里循環嗎?
你的例子中這些項就是?$(ls *.tar.gz *.gz) 這個東西。
先不管 $ 和 (),單看?ls *.tar.gz *.gz,這是一個 ls 命令,會列出當前目錄下所有的 .tar.gz .gz 結尾的文件。而所列出的這些文件名就是需要循環的項。
也就是說你想要的循環項不是“ls *.tar.gz *.gz”這三個字,而是這句 ls 命令的執行結果。
像這樣,想要在 bash 腳本中得到一個命令的執行結果,叫做“命令替換”。它的語法就是用 $( ?) 把命令括起來,到腳本運行時這里就會替換為該命令的執行結果了。
所以你這里既然需要的是 ls 的執行結果,那就要寫?$(ls *.tar.gz *.gz)。
既然 $(...) 是“命令替換”的語法格式,那當然不能去掉 $ 了。
多說一些:
如果去掉 $ 會怎么樣呢? ?只剩下 (ls *.tar.gz *.gz),這里出現小括號是不合法的,所以腳本在執行到這里時會直接報錯。
再多說一些:
前面說 in 后面的這些“字”就是循環項。 其實呢,for 語句會嘗試對這些“字”做“路徑名展開”?!奥窂矫归_”就是指展開那些路徑通配符 * ? 什么的。
所以如果你在 in 后面直接寫?*.tar.gz,這里會直接被替換為所有 *.tar.gz 結尾的文件名,這樣你甚至不需要用 ls 命令來幫你列出它們。
所以這句你直接寫成?for i in *.tar.gz *.gz 也是可以的。
但有一點:如果沒能成功進行路徑名展開(也就是說目錄下沒有這樣的文件),那 *tar.gz(或 *.gz)還是會被當作一個單純的字來用。
最后多說一點:
對于前面一人的回答。$ 放在變量名前才是“變量展開”。而這里根本就沒有變量的事,這只是“命令替換”而已。
- 2 回答
- 0 關注
- 2046 瀏覽
添加回答
舉報