Bash
一個像其他語言一樣接受參數的bash函式?
我有一個bash函式來設置
$PATH
這樣的——assign-path() { str=$1 # if the $PATH is empty, assign it directly. if [ -z $PATH ]; then PATH=$str; # if the $PATH does not contain the substring, append it with ':'. elif [[ $PATH != *$str* ]]; then PATH=$PATH:$str; fi }
但問題是,我必須為不同的變數編寫不同的函式(例如,為
$CLASSPATH
likeassign-classpath()
等編寫另一個函式)。我找不到將參數傳遞給 bash 函式的方法,以便我可以通過引用訪問它。如果我有類似的東西會更好——
assign( bigstr, substr ) { if [ -z bigstr ]; then bigstr=substr; elif [[ bigstr != *str* ]]; then bigstr=bigstr:substr; fi }
任何想法,如何在 bash 中實現類似上面的東西?
在
bash
你可以使用${!varname}
擴展另一個內容所引用的變數。例如:$ var=hello $ foo () { echo "${!1}"; } $ foo var hello
從手冊頁:
${!prefix*} ${!prefix@} Names matching prefix. Expands to the names of variables whose names begin with prefix, separated by the first character of the IFS special variable. When @ is used and the expansion appears within double quotes, each variable name expands to a separate word.
此外,要設置內容引用的變數(沒有 的危險
eval
),您可以使用declare
. 例如:$ var=target $ declare "$var=hello" $ echo "$target" hello
因此,您可以像這樣編寫函式(請注意,因為如果您
declare
在函式中使用,則必須給出,-g
否則變數將是本地的):shopt -s extglob assign() { target=$1 bigstr=${!1} substr=$2 if [ -z "$bigstr" ]; then declare -g -- "$target=$substr" elif [[ $bigstr != @(|*:)$substr@(|:*) ]]; then declare -g -- "$target=$bigstr:$substr" fi }
並像這樣使用它:
assign PATH /path/to/binaries
請注意,我還糾正了一個錯誤,如果 if
substr
已經是 的冒號分隔成員之一的子字元串bigstr
,但不是它自己的成員,則不會添加它。例如,這將允許添加/bin
到PATH
已經包含/usr/bin
. 它使用extglob
集合來匹配字元串的開頭/結尾或冒號,然後再匹配其他任何內容。如果沒有extglob
,替代方案將是:[[ $bigstr != $substr && $bigstr != *:$substr && $bigstr != $substr:* && $bigstr != *:$substr:* ]]