Shell-Script
在 find -exec 呼叫中執行使用者定義的函式
我在 Solaris 10 上,我用 ksh (88)、bash (3.00) 和 zsh (4.2.1) 測試了以下內容。
以下程式碼不會產生任何結果:
function foo { echo "Hello World" } find somedir -exec foo \;
find 確實匹配了幾個文件(如用 替換所示
-exec ...
)find
。以下是該
man find
頁面的內容-exec
:-exec command 如果執行的命令返回一個 零值作為退出狀態。結尾 命令必須用轉義符打斷 分號 (;)。命令參數 {} 是 替換為目前路徑名。如果 -exec 的最後一個參數是 {} 而你 指定 + 而不是分號 (;), 該命令被呼叫的次數更少,與 {} 替換為路徑名組。如果 該命令的任何呼叫都會返回一個 非零值作為退出狀態,找到 返回非零退出狀態。
我可能會做這樣的事情:
for f in $(find somedir); do foo done
但我害怕處理欄位分隔符問題。
是否可以從呼叫中呼叫 shell 函式(在同一個腳本中定義,讓我們不要為範圍問題而煩惱)
find ... -exec ...
?我嘗試了兩者
/usr/bin/find
並/bin/find
得到了相同的結果。
A
function
對 shell 來說是本地的,因此您需要find -exec
生成一個 shell 並在該 shell 中定義該函式,然後才能使用它。就像是:find ... -exec ksh -c ' function foo { echo blan: "$@" } foo "$@"' ksh {} +
bash
允許通過環境導出函式export -f
,因此您可以(在 bash 中):foo() { ...; } export -f foo find ... -exec bash -c 'foo "$@"' bash {} +
ksh88
必須typeset -fx
導出功能(不是通過環境),但只能由 執行的 she-bang less 腳本使用ksh
,所以不能使用ksh -c
.另一種選擇是:
find ... -exec ksh -c " $(typeset -f foo)"' foo "$@"' ksh {} +
也就是說,用於
typeset -f
轉儲foo
內聯腳本中的函式定義。請注意,如果foo
使用其他功能,您還需要轉儲它們。
ps -f
或者,您可以通過環境變數傳遞它,而不是在命令行上傳遞函式定義(例如在輸出中可見):FUNCDEFS=$(typeset -f foo) find ... -exec ksh -c ' eval "$FUNCDEFS" && unset -v FUNCDEFS && foo "$@"' ksh {} +
(
unset -v FUNCDEFS
避免污染由該foo
函式啟動的命令的環境(如果有))。