Bash

使用來自使用 globbing 的函式的路徑

  • November 4, 2019

眾所周知,解析 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 語言(如bash4.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函式採用一個變數的名稱 in list,這是一個名稱引用變數。這意味著任何使用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
}

也就是說,如果要返回給呼叫者,則循環擴展模式並將項目附加到列表中。

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