それ以外の場合は、APP_ENV
「prod」は空でなければなりません。DATABASE_DISABLE_MIGRATIONS
true
〜しない限り DATABASE_DISABLE_MIGRATIONS
空またはnullです。つまり、価値は尊重されるべきです自動割り当ては、次の場合にのみ発生する必要があります。未設定。
オリジナルDATABASE_DISABLE_MIGRATIONS |
APP_ENV |
新しいDATABASE_DISABLE_MIGRATIONS |
---|---|---|
空または空 | どの | 元の価値を維持する |
長さがゼロ以外の文字列 | どの | 元の価値を維持する |
未設定 | 「製品」 | 空 |
未設定 | 空でも「prod」でもない | 「本物」 |
私はシェル(POSIX)を学び始め、次のコードを使ってこれを成功させました。
#!/bin/sh
if [ "${DATABASE_DISABLE_MIGRATIONS+set}" != set ]; then
: ${DATABASE_DISABLE_MIGRATIONS:=$( [ "$APP_ENV" = "prod" ] || echo "true" )}
fi
# Just for debug (not meant to be in the single-line assignment of course)
if [ -z "$DATABASE_DISABLE_MIGRATIONS" ]; then
echo "Empty value, migrations ENABLED"
else
echo "Not empty value, migrations DISABLED"
fi
上記のコードを1行の文で書くことはできますか?
設定されていない文字列、null、または空の文字列を考慮すると、1行の文を作成するのは簡単です。私はしばしば以下を使用します。
: ${FOO:=$( [ "$APP_ENV" = "prod" ] || echo "true" )}
変数が設定されていない場合は、nullまたは空で、「prod」でない場合はFOO
値を取得します。true
FOO
APP_ENV
たぶん似たような「ショートカット」がありませんか?
答え1
2つの変数を使用するCaseステートメントは次のとおりです。
case "${DATABASE_DISABLE_MIGRATIONS}:${APP}" in
?*:* | "":prod) # not empty, or prod
echo "Not empty value, migrations DISABLED"
;;
*) echo "Empty value, migrations ENABLED"
;;
esac
しかし、これは「空」と「未設定」を区別しません。変数の値の1つにコロンが含まれている場合でも、なりすましの可能性があります。
に基づいて
オリジナルDATABASE_DISABLE_MIGRATIONS |
APP_ENV |
新しいDATABASE_DISABLE_MIGRATIONS |
---|---|---|
空または空 | どの | 元の価値を維持する |
長さがゼロ以外の文字列 | どの | 元の価値を維持する |
未設定 | 「製品」 | 空 |
未設定 | 空でも「prod」でもない | 「本物」 |
自分をPOSIXに制限しないでください。 「未設定」は調整変数を使用するには、次のようにします。
if [[ ! -v DATABASE_DISABLE_MIGRATIONS ]]; then
if [[ $APP == prod ]]; then
DATABASE_DISABLE_MIGRATIONS=""
else
DATABASE_DISABLE_MIGRATIONS=true
fi
fi
これは明らかにあなたの一行の希望を満たしていませんが、あなたの意図を伝える最も読みやすい方法だと思います。
答え2
注文する:
[ -z "${DATABASE_DISABLE_MIGRATIONS+x}" ] && [ "$APP_ENV" != "prod" ] && DATABASE_DISABLE_MIGRATIONS=true
説明する:
ㅏコメントこの情報を使用して変数を確認することを示します。
[ -z "$DATABASE_DISABLE_MIGRATIONS" ]
この情報は質問の一部でなければなりません。
"$DATABASE_DISABLE_MIGRATIONS"
(または)を使用しない限りset -u
、設定されていない変数または空の文字列に対して拡張結果が同じであるため、set -o nounset
要件が簡素化されます。設定されていない変数を明示的なnull値に置き換えないでください。"prod"
設定しないままにしておくと同じテスト結果が得られるからです。
したがって、アルゴリズムは次のように単純化できます。
- (DATABASE_DISABLE_MIGRATIONS が設定されておらず、APP_ENV が "prod" でない場合) DATABASE_DISABLE_MIGRATIONS を "true" に設定します。
- (そうでなければ何もしない)
もちろん、これは複数行で書くことができるので、コードはより明確になりますが、1行ではなく、質問に対する解決策よりはるかに短くはありません。
if [ -z "${DATABASE_DISABLE_MIGRATIONS+x}" ] && [ "$APP_ENV" != "prod" ]
then
DATABASE_DISABLE_MIGRATIONS=true
fi
答え3
したがって、変数が設定されていない場合はデフォルト値に設定し、それ以外の場合は元の値を維持しますか? (ここではデフォルトは他の変数によって異なりますが、それが気を散らさないようにしましょう。)
もしそうなら、次のようにする方が良いかもしれません。
# don't disable migrations in production by default
if [ "$APP_ENV" = prod ]; then
default_DATABASE_DISABLE_MIGRATIONS=
else
default_DATABASE_DISABLE_MIGRATIONS=true
fi
# set default value if unset
if [ "${DATABASE_DISABLE_MIGRATIONS+set}" != set ]; then
DATABASE_DISABLE_MIGRATIONS=$default_DATABASE_DISABLE_MIGRATIONS
fi
またはより短いもの:
# don't disable migrations in production by default
default_DATABASE_DISABLE_MIGRATIONS=true
if [ "$APP_ENV" = prod ]; then
default_DATABASE_DISABLE_MIGRATIONS=
fi
# set default value if unset
: "${DATABASE_DISABLE_MIGRATIONS=$default_DATABASE_DISABLE_MIGRATIONS}"
関連する値に基づいたコードゴルフは、他の値に対しても同様のロジックを使用する必要がある場合はコード全体を変更する必要があるため、非生産的なようです。他の同様のケースに適用できる簡単なソリューションを開発することをお勧めします。最後の行は、質問のタイトルで要求されたものとほぼ同じですが、変数が設定されていない場合は、1行のシェル割り当てのみを実行します。 ("${var:=default}"
空の値セットにも機能します。)
また、最終的な変数が否定されない場合、読者にとってより明確になる可能性があることも指摘したいと思います。[ -z "$DATABASE_DISABLE_MIGRATIONS" ]
デフォルトでは、「移行が無効になっていない場合」などの変数の使用とテストに言及しました。これは「移行が有効になっている場合」と同じです。変数を使用すると簡単に作成できます$DATABASE_ENABLE_MIGRATIONS
。
答え4
可能:
case ${DATABASE_DISABLE_MIGRATIONS++}:$APP_ENV in
(:prod) DATABASE_DISABLE_MIGRATIONS= ;;
(:* ) DATABASE_DISABLE_MIGRATIONS=true;;
esac
他のコードと同様に、1行に挿入して行をリンクするか、次のように圧縮することもできます。
case ${DATABASE_DISABLE_MIGRATIONS++}:$APP_ENV in(:prod)DATABASE_DISABLE_MIGRATIONS=;;(:*)DATABASE_DISABLE_MIGRATIONS=true;esac
)しかし私は利点を見ませんでした。
実行とは$(... echo ...)
、追加のプロセスを分岐し(ksh93を除く)、コマンドをecho
実行し、パイプを介してそのコマンドを送受信することを意味します。これは数十万以上のCPU命令を意味しますが、これらの単純なシェル割り当てとパターンマッチングはわずか数百しかありません。だから私には少し愚かな感じがします。