$PATH
次のように設定できるbash機能があります。
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
別の関数を作成するassign-classpath()
など)。参照としてアクセスできるように bash 関数にパラメータを渡す方法が見つかりません。
似たようなものがあればもっといいと思います -
assign( bigstr, substr )
{
if [ -z bigstr ]; then
bigstr=substr;
elif [[ bigstr != *str* ]]; then
bigstr=bigstr:substr;
fi
}
bashで上記のようなものを実装する方法を知っていますか?
ベストアンサー1
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
substr
ifがすでにコロンで区切られたメンバーの1つのサブストリングですが、それbigstr
自体のメンバーではない場合に追加されないバグも修正されました。たとえば、すでに含まれているもの/bin
に追加できます。これは、文字列やコロンの開始/終了などの項目を一致させるためにセットを使用します。そうでない場合、代替は次のとおりです。PATH
/usr/bin
extglob
extglob
[[ $bigstr != $substr && $bigstr != *:$substr &&
$bigstr != $substr:* && $bigstr != *:$substr:* ]]