シェル変数を設定し、それをシェルスクリプトの一部としてコマンドに渡したいのですが、コードは次のようになります。
SLS_DEBUG_TEXT=""
if [ "$ENABLE_DEBUG_LOGGING" = "true" ]; then
SLS_DEBUG_TEXT="SLS_DEBUG=* "
fi
$SLS_DEBUG_TEXT sls create_domain -v $AWS_PROFILE_FLAG --stage $STAGE // gives error
#SLS_DEBUG=* sls create_domain -v $AWS_PROFILE_FLAG --stage $STAGE // works correctly
私が受け取ったエラーは次のとおりです。
./sls-deploy.sh: line 110: SLS_DEBUG_TEXT: command not found
このif
説明はほとんど関係ありませんが、変数を条件付きに設定する必要があることを示したかったです(つまり、常にデバッグログを有効にしたくはありません)。コメントアウトされたコードスニペットの最後の行は、デバッグロギングが有効になって正しく機能するコマンドの外観です。
こことStack Overflowで変数を設定すると、等号の間のスペースが原因で問題が発生した以前の投稿がいくつか見つかりました(はい)しかし私はしませんでした。考える私はここでこの罠に陥った。
ご協力ありがとうございます。
答え1
$SLS_DEBUG_TEXT
シェルがその値を割り当てとして処理するステップの後、拡張は遅すぎます。したがって、変数の値はコマンドとして扱われます。
あなたができることは以下を使うことですenv
:
SLS_DEBUG_TEXT='SLS_DEBUG=*'
env "$SLS_DEBUG_TEXT" sls create_domain -v "$AWS_PROFILE_FLAG" --stage "$STAGE"
周囲の引用に注意してください各単一変数が拡張されます。。
可能性が空であるか設定されていない場合、上記の場合は名前のないコマンドを試みるため、SLS_DEBUG_TEXT
エラーが発生します。env
この問題を解決するには、次を使用できます。
SLS_DEBUG_TEXT='SLS_DEBUG=*'
env ${SLS_DEBUG_TEXT:+"$SLS_DEBUG_TEXT"} sls create_domain -v "$AWS_PROFILE_FLAG" --stage "$STAGE"
変数が設定され、nullでない場合${SLS_DEBUG_TEXT:+"$SLS_DEBUG_TEXT"}
に展開されます。"$SLS_DEBUG_TEXT"
それ以外の場合は何も拡張されません(この場合は空の文字列も拡張されません"$SLS_DEBUG_TEXT"
)。
SLS_DEBUG_TEXT='SLS_DEBUG=* '
また、コードのように次のスペースがある場合は、*
プロセス環境の値の一部になります。これが意図的なものかどうかはわかりません。SLS_DEBUG
sls
私はまた、あなたが引用したエラーメッセージが次のように見えました。
./sls-deploy.sh: line 110: SLS_DEBUG_TEXT: command not found
私にとって、これは$
変数名を使用する前に、変数名を使用せずにスクリプトのある時点で変数名を使用していることを意味します。これは、現在経験している主な問題とはまったく関係がない可能性があります。あなたのコード展示する代わりにエラーが発生します。
./sls-deploy.sh: line NNN: SLS_DEBUG=*: command not found
答え2
これシェル文法は、語彙解析フェーズで割り当て語を識別します。、パラメータ拡張が発生するはるかに前です。パラメータを次に拡張できますが、注文する、タスクに拡張できません。その時点では、(作成したとおり"SLS_DEBUG=*" sls ...
)テキストが同じであってもコマンドとして扱われます。
これはシェルコマンド言語の解析と評価の奇妙な側面です。特定の種類の動作は、コードを初めて読み取るときに語彙的に決定され、これらの動作は正常に動作しても後で回復できません。現れるテキストの交換で動作します。
あなたできるSLS_DEBUG_TEXT="eval SLS_DEBUG='*' "
コマンドの残りの部分にシェルメタ文字を含めることができると、潜在的な問題が発生する可能性がありますが、この方法は機能します。別のオプションは、条件付きで関数を定義することです。
sls_debug() { :; }
if [ "$ENABLE_DEBUG_LOGGING" = "true" ]; then
sls_debug() {
SLS_DEBUG='*' "$@"
}
fi
sls_debug sls create_domain ...
または(おそらくより明確に)$ENABLE_DEBUG_LOGGING
内部的にのみ確認する機能も機能するか明示的にすることができenv "$SLS_DEBUG_TEXT" ...
ますeval "$SLS_DEBUG_TEXT" ...
。
答え3
完全性を期すために、これが私が問題を解決した方法です。コサロナンダの答えそしてマイケル・ホーマーの答え。
function executeServerlessCommand() {
if [ "$ENABLE_SLS_DEBUG_LOGGING" = "true" ]; then
SLS_DEBUG='*' "$@"
else
"$@"
fi
}
executeServerlessCommand sls create_domain -v ${AWS_PROFILE_FLAG:+"$AWS_PROFILE_FLAG"} --stage "$STAGE"
いくつかの注意:
- 実行するコマンドを受け入れ、
ENABLE_SLS_DEBUG_LOGGING
変数を確認し、SLS_DEBUG=*
trueの場合はコマンドの前に追加し、それ以外の場合は提供されたコマンドを実行する関数を作成しました。 - 私が使用する
${a:+"$a"}
変数構文は、AWS_PROFILE_FLAG
変数値がすでに設定されている場合にのみ追加します。以前は、この変数は正しく参照されませんでした。