2つ以上の変数に&&と||演算子を正しく使用するには?

2つ以上の変数に&&と||演算子を正しく使用するには?

複数の変数の状態を比較しようとしています。ユースケースは、他のオプションから利用可能な実行可能ファイルに基づいて複数の「モード」のうちの1つのみを選択(または自動選択)する必要があるスクリプトです。いくつかの構文図は次のとおりです。

 [ [--fzf,-f]|[--rofi,-r]|[--dmenu,-d] ]

これらの変数は、コマンド引数が存在するかどうかによって定義されます。たとえば、--fzfコマンドライン引数にまたはがある場合、関連変数は "1"に設定され、ユーザーがスクリプトを実行しようとしていることを示します。より良い方法の節が不足しています。-ffzffzf mode

次の演算子ステートメントは、&&コマンドラインにコマンドパラメータがない場合に発生する状況を説明します。デフォルトでは、「モード」を選択しないと、スクリプトは階層化された方法で使用する1つのモードのみを自動的に選択します。

次の演算子ステートメントは、||(ユーザー)パターンを選択したがデフォルトの実行可能ファイルが見つからない場合に発生する状況に対処する必要があります。

これは&&演算子の元のバージョンです:

if [[ $fzf = 0 && $rofi = 0 ]]; then
        if command_exists fzf; then
            fzf=1
        elif command_exists rofi; then
            rofi=1
        fi
    fi

到着

if [[ $fzf = 0 && $rofi = 0 && $dmenu = 0 ]]; then
        if command_exists fzf; then
            fzf=1
        elif command_exists rofi; then
            rofi=1
        elif command_exists dmenu; then
            dmenu=1
        fi
    fi

最後に、||の元のテキストは次のようになります。オペレーター:

if [[ $rofi = 1 || $fzf = 0 ]]; then
        command_exists rofi || die "Could not find rofi in \$PATH"
        menu="$rofi_cmd"
elif [[ $fzf = 1 || $rofi = 0 ]]; then
        command_exists fzf || die "Could not find fzf in \$PATH"
        menu="$fzf_cmd"
else
        die "Could not find either fzf or rofi in \$PATH"
fi

到着

if [[ $rofi = 1 || $fzf = 0 || $dmenu = 0 ]]; then
        command_exists rofi || die "Could not find rofi in \$PATH"
        menu="$rofi_cmd"
    elif [[ $fzf = 1 || $rofi = 0 || $dmenu = 0 ]]; then
        command_exists fzf || die "Could not find fzf in \$PATH"
        menu="$fzf_cmd"
    elif [[ $dmenu = 1 || $rofi = 0 || $fzf = 0 ]]; then
        command_exists dmenu || die "Could not find dmenu in \$PATH"
        menu="$dmenu_cmd"
    else
        die "Could not find either fzf or rofi or dmenu in \$PATH"
    fi

これはエラーを発生させないようですが、これを行う正しい方法ではなく、期待どおりに動作しない可能性があると思います(-x使用して出力を表示したときに誤った値を報告するようです)。

私はこれを知っていますこれしかし、(まだ)2つ以上の変数がある例が見つかりませんでした(上記で試したようなもの)。

上記の原文はいくつか抜粋されました。これスクリプト。基本的にサポートを追加しようとしています。なぜなら、サポートは(上に示されている)とサポートされてdmenuいるからです。rofifzf

完全な修正は次のとおりです。スクリプトpassword-store依存関係として必要です。

私はBash 5.0.3を使用しています。

2つ以上の変数に&&と||演算子を正しく使用するには?

ベストアンサー1

ユーザーがそれらのうちの1つだけを選択した場合は、変数を使用して選択内容を保持し、各オプションの変数を削除します。とにかく、私たちはすべての組み合わせにあまり興味を持っていません。 3つの中から1つを選択し、「設定解除/デフォルト」に1つを選択するだけです。

だから:

#!/bin/sh
cmd=             # empty value for default
case "$1" in
    --rofi|-r)  cmd=rofi ;;
    --fzf|-f)   cmd=fzf ;;
    --dmenu|-d) cmd=dmenu ;;
esac

if [ -z "$cmd" ]; then
    echo "no command set, looking for default"
    if command_exists fzf; then
        cmd=fzf
    elif
        ...
    fi
fi

echo "running with command $cmd"
# actually do something

ここで選択したパターンはに保存されますcmd。実際、私はユーザーに2つのコマンドを与える可能性さえ与えませんでした。最初のパラメータをフラグとして読むだけです。これで、またはgetoptを使用すると実際には機能しませんが、getoptsモードを設定する前にモードがすでに(再)設定されていることを確認できます。

#!/bin/sh
error_if_cmd_set() {
    if [ -n "$1" ]; then
        echo "command already set"
        exit 1
    fi
}
cmd=
for arg in "$@"; do
    case "$1" in
        --rofi|-r)  error_if_cmd_set "$cmd"; cmd=rofi ;;
        --fzf|-f)   error_if_cmd_set "$cmd"; cmd=fzf ;;
        --dmenu|-d) error_if_cmd_set "$cmd"; cmd=dmenu ;;
    esac
done
# ...
echo "using command $cmd"

おすすめ記事