$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:* ]]
答え2
Bash 4.3の新機能は&-n
オプションです。declare
local
func() {
local -n ref="$1"
ref="hello, world"
}
var='goodbye world'
func var
echo "$var"
出力されるのはですhello, world
。
答え3
パラメータの設定に使用できますeval
。このコマンドのガイドラインは以下にあります。ここ。次の使用法はeval
正しくありません。
無効(){ 評価$1=$2 }
追加の評価にはeval
以下を使用する必要があります。
分配する(){ 評価$1='$2' }
次の機能を使用した結果を確認してください。
$X1='$X2' $X2='$X3' $X3='xxx' $ $エコ:$X1: :$X2: $エコ:$X2: :$X3: $エコ:$X3: :トリプルX: $ $エラーY $X1 $エコ:$Y: :$X3: $ $割り当てY $X1 $エコ:$Y: :$X2: $ $Y "hello world" 割り当て $エコ:$Y: :こんにちは世界: $#次の内容は予期しない内容かもしれません。 $割り当てZ $ Y $echo ":$Z:" :こんにちは: $ # したがって、2 番目のパラメータが変数の場合は、引用符で囲む必要があります。 $割り当てZ "$Y" $echo ":$Z:" :こんにちは世界:
ただし、それを使用せずに目標を達成できますeval
。私はこの簡単な方法を好む。
次の関数は正しい方法で置換を実行します。 (希望)
増加する(){ 地域電流=$1 ローカル増分=$2 地域の新しい if [[ -z $CURRENT ]]; 新しい=$改善 エリーフ[[! ( ( $CURRENT = $AUGMENT ) || ( $CURRENT = $AUGMENT:* ) || \ ( $current = *:$AUGMENT ) || ( $current = *:$AUGMENT:* ) ] ]]; 新規=$現在:$改善 その他 新しい=$現在 フィリピン諸島 エコ「$鳥」 }
次の出力を確認してください。
拡張 /usr/bin /bin /usr/bin:/bin 拡張 /usr/bin:/bin /bin /usr/bin:/bin 拡張 /usr/bin:/bin:/usr/local/bin /bin /usr/bin:/bin:/usr/local/bin /bin:/usr/bin /bin 強化 /bin:/usr/bin /bin /bin 強化 /ゴミ箱 /usr/bin 拡張: /bin /usr/bin::/bin 拡張 /usr/bin:/bin: /bin /usr/bin:/bin: /usr/bin:/bin:/usr/local/bin:/bin を展開します。 /usr/bin:/bin:/usr/local/bin: /bin:/usr/bin: /bin 強化 /bin:/usr/bin: /binの強化: /bin /ゴミ箱: 改善:/bin ::/ゴミ箱 "/usr lib" "/usr bin" を展開します。 /usrlib:/usrbin "/usr lib:/usr bin" "/usr bin" を展開します。 /usrlib:/usrbin
この関数を使用して、augment
次の方法で変数を設定できます。
PATH=`PATH /bin 拡張` CLASSPATH=`CLASSPATH /bin 追加` LD_LIBRARY_PATH=`拡張LD_LIBRARY_PATH /usr/lib`
答え4
assign ()
{
if [ -z ${!1} ]; then
eval $1=$2
else
if [[ ${!1} != *$2* ]]; then
eval $1=${!1}:$2
fi
fi
}
$ echo =$x=
==
$ assign x y
$ echo =$x=
=y=
$ assign x y
$ echo =$x=
=y=
$ assign x z
$ echo =$x=
=y:z=
これは適切ですか?