bash 関数 - 変数内の関数の標準出力値を取得し、関数の外側で変数を変更します。

bash 関数 - 変数内の関数の標準出力値を取得し、関数の外側で変数を変更します。

特定の要求のために、bash関数のすべてのstdout出力を変数( "F_MY_FUNC_R")に格納する必要がありますが、次のものに基づいていくつかの変数( "VAL_A"と "VAL_B")の値を変更する関数も必要です。以下のコード。

質問:VAL_AとVAL_B変数が変更されていないのはなぜですか?解決策はありますか?

パスワード

VAL_A="none"
VAL_B="none"
f_my_func() {
    echo "some info some info some info some info some info "
    echo "some info some info some info some info some info "
    echo "some info some info some info some info some info "
    echo "some info some info some info some info some info "
    VAL_A="some value"
    VAL_B="some value"
}
F_MY_FUNC_R=$(f_my_func)
echo "$F_MY_FUNC_R"
echo "$VAL_A"
echo "$VAL_B"

出力

[root@localhost some_folder]# echo "$F_MY_FUNC_R"
some info some info some info some info some info 
some info some info some info some info some info 
some info some info some info some info some info 
some info some info some info some info some info 
[root@localhost some_folder]# echo "$VAL_A"
none
[root@localhost some_folder]# echo "$VAL_B"
none

ありがとうございます! =D

答え1

サブシェルはシェルの基本ルールです。できない親変数または環境を変更します。サブシェル内で関数を実行することは$(f_my_func)この規則の影響を受け、親変数VAL_AとVAL_Bは変更されません。

関数の親変数を本当に変更する必要がある場合は、関数の出力をキャプチャするのではなく、出力を別の変数に設定してください。

VAL_A="none"
VAL_B="none"
f_my_func() {
    nl=$'\n'
    F_MY_FUNC_R="some info some info some info some info some info $nl"
    F_MY_FUNC_R+="some info some info some info some info some info $nl"
    F_MY_FUNC_R+="some info some info some info some info some info $nl"
    F_MY_FUNC_R+="some info some info some info some info some info "
    VAL_A="some value"
    VAL_B="some value"
}
f_my_func
echo "$F_MY_FUNC_R"
echo "$VAL_A"
echo "$VAL_B"

答え2

これが私の「汚い」解決策です... = D

メモ:echo私が言ったように、私の実際の機能は大きいので、その機能の出力を(デフォルトで)使い続けたいと思いますF_MY_FUNC_OP。それに加えて、私のロギング方式はF_MY_FUNC_OP多くのレガシーコンポーネントを使用して設定します。

VAL_A="none"
VAL_B="none"
f_my_func() {
    echo "$(date)"
    VAL_A="some value"
    VAL_B="some value"
}
f_my_func > f_my_func_op 2>&1
F_MY_FUNC_OP=$(cat f_my_func_op)
rm -f "f_my_func_op"
echo "$F_MY_FUNC_OP"
echo "$VAL_A"
echo "$VAL_B"

これにより、関数を実行し、対応する stderr と stdout をファイルにリダイレクトし、関数外の変数 ("$VAL_A" および "$VAL_B" の場合) を操作できます。それ以外の場合(「F_MY_FUNC_OP=例:$(f_my_func)」または「F_MY_FUNC_OP=`f_my_func`」)、関数は「サブシェル」で実行され、これらの変数では機能できません。

@jesse_b、@AdminBee、@Isaac ありがとうございます!=D

関連情報