条件付きプロセスの交換

条件付きプロセスの交換

複数のパラメーターを含むコマンドがあります。

my_command --arg1 <arg1> \
    --arg2 <arg2> \
    --arg3 <arg3>

my_command渡されても渡されなくてもよい、さまざまなパラメータの値を設定する関数で呼び出しをラップします。

run_my_command() {
    if [[ ... ]]; then
        ARG1FLAGS="--arg1 $ARG1"
    else
        ARG1FLAGS=''
    fi
    if [[ ... ]]; then
        ARG2FLAGS="--arg2 $ARG2"
    else
        ARG2FLAGS=''
    fi
    if [[ ... ]]; then
        ARG3FLAGS="--arg3 $ARG3"
    else
        ARG3FLAGS=''
    fi

    my_command $ARG1FLAGS \
        $ARG2FLAGS \
        $ARG3FLAGS
}

場合によっては、ファイル名引数を次に渡す必要がありますmy_command

run_my_command() {
    # ...
    if [[ ... ]]; then
        FILEARG="--input_file $SOME_FILE"
    else
        FILEARG=''
    fi

    my_command $FILEARG \
        ...
}

これらすべてがうまくいきます。これで、条件付きでプロセス置換を使用したいのですが、FILEARG当然動作しません。

run_my_command() {
    # ...
    if [[ ... ]]; then
        FILEFLAG='--input_file'
        FILEARG=<(other_cmd)
    else
        FILEARG=''
    fi

    my_command $FILEFLAG $FILEARG \
        ...
}

ランタイムによってmy_command匿名$FILEARGパイプのように見えるのが/dev/fd/63閉じたからです。

今、すべてを条件付きで入れて、my_commandこの問題を解決しました。

run_my_command() {
    # Get ARG1, ARG2, ARG3...
    if [[ ... ]]; then
        my_command --input_file <(other_cmd) \
            $ARG1FLAGS \
            $ARG2FLAGS \
            $ARG3FLAGS
    else
        my_command $ARG1FLAGS \
            $ARG2FLAGS \
            $ARG3FLAGS
    fi
}

しかし、私は繰り返しが好きではありません。を使って何かをしたり、他の関数evalに入れることができるようですが、my_commandまだ把握していません。my_command呼び出し全体を複製せずに読み取り可能なファイルを生成するために条件付きでプロセス置換を使用するにはどうすればよいですかmy_command

私はbash 4.4.19を実行しています。驚いたことに、bash 3.2.57は以下のBash Hackers Wikiで提案された方法で動作するようです。

doit() {
    local -r FOO=<(echo hi)
    cat $FOO
}

doit

# bash 3.2.57:
$ ./test.sh
hi
# bash 4.4.19:
$ ./test.sh
cat: /dev/fd/63: Bad file descriptor

以下は私が確認した質問ですが、次から有効な答えを得ることはできません。

さらに、バッシュハッカーウィキノートむしろ神秘的に:

プロセス置換が関数への引数、関数呼び出し中の環境変数、または関数内の割り当てに拡張されると、プロセス置換は、関数内または呼び出されるすべてのコマンドで使用できるように「開いたまま」になります。またはそれを設定した関数が返されるまで。呼び出し先で同じ変数がリセットされると、新しい変数がローカルでない限り、以前のプロセス置換が解放され、呼び出し先が返されたときに呼び出し側は変数を使用できません。

デフォルトでは、関数内変数に展開されるプロセス置換は、プロセス置換が発生する関数が返されるまでオンになっています。これは、関数呼び出し元が設定したローカル変数に割り当てられている場合も同様です。ダイナミックレンジは閉じることを防ぎません。

ただし、関数の変数にプロセス置換を割り当てるだけでは、「開いたままにする」ことはできません。

ベストアンサー1

これは質問と似ていますが、他のパラメータを単一の変数ではなく配列に入れると、重複が減ります。$ARGnFLAGS

いずれにせよ、これは単語の分割やファイル名のグロービングを中断することなくコマンドの引数を取得できるため、これは正しいことです。

run_my_command() {
    args=()
    if [[ ... ]]; then
        args+=(--arg1 "$ARG1")
    fi
    if [[ ... ]]; then
        args+=(--arg2 "$ARG2")
    fi

    if [[ ... ]]; then
        my_command --input_file <(other_cmd) "${args[@]}"
    else
        my_command "${args[@]}" 
    fi
}

おすすめ記事