Bash
使用來自使用 globbing 的函式的路徑
眾所周知,解析 ls 的輸出通常是一個壞主意,一種解決方案是使用 globbing 而不是 ls 來“安全地”遍歷目錄中的文件。
for path in /path/to/search/*; do ... # Do more filtering ... echo "$path" done
此函式將進一步過濾 glob 匹配的一些結果,並輸出剩餘路徑。
但是,如果我想在其他地方重用這個邏輯,我可以通過一個函式安全地使用它的輸出並循環它嗎?
function myglob() { for path in /path/to/search/*; do ... # Do more filtering ... echo "$path" done } function myExample() { results=$(myglob) for i in "$results"; do echo "$i" done }
或者我必須總是複制全域邏輯並對內部邏輯進行微小的更改?
不,您不能重複使用循環輸出,因為這會
ls
準確地複制問題,並添加echo
可能解釋文件名中的反斜杠的問題。相反,如果您使用的是具有數組和名稱引用的 shell 語言(如
bash
4.3+ 中),則可以稍作不同:myglob () { declare -n list="$1" list=( /path/to/search/* ) } myexample () { local results=() myglob results for pathname in "${results[@]}"; do printf '%s\n' "$pathname" done # or shorter, just # printf '%s\n' "${results[@]}" }
在這裡,該
myglob
函式採用一個變數的名稱 inlist
,這是一個名稱引用變數。這意味著任何使用list
實際上都會使用命名變數。該函式只是擴展 glob 並將結果儲存在list
一個數組中。然後該函式使用字元串
myexample
呼叫。因此,變數 in將引用該變數,並將擴展模式儲存在其中。myglob``results``list``myglob``results
然後該函式繼續
results
用作項目數組。如果
myglob
需要做過濾:myglob () { declare -n list="$1" list=() for pathname in /path/to/search/*; do # decide whether to use "$pathname" or not # then, if it is to be used, list+=( "$pathname" ) done }
也就是說,如果要返回給呼叫者,則循環擴展模式並將項目附加到列表中。