
いくつかの簡単なフラグを使用して実行スクリプトを作成しようとしています。/bin/sh
#!/bin/sh
set -eux
if [ "$DEBUG" = "true" ]; then
debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=$SUSPEND,address=$DEBUG_PORT"
else
debug=''
fi
serv="--server.port=${SERVER_PORT}"
prop="--spring.profiles.active=${PROFILES}"
all="${serv:-} ${prop:-}"
java "${debug:-}"-jar /opt/someJar.jar "${all:-}"
今、私たちは説明できず、なぜそのようなことが起こるのか私たちが見つけることができないいくつかの問題を見つけました。
"${debug:-}"-jar
席がないので参考にしてください。スペースを入れると、「javaはメインクラスを見つけるかロードできません」というメッセージでアプリケーションがクラッシュします。スペースを削除すると、期待どおりに機能します。- 2つの変数
serv
とprop
。これら2つをjavaコマンドの最後に入れると、"${serv:-}" "${prop:-}"
これら2つのパラメータはアプリケーションから別々に渡されます。しかし、"${all:-}"
Javaの例外から増やすと、これら2つが互いに接続されていることがわかります。
Caused by: java.lang.NumberFormatException: For input string: "1234--spring.profiles.active=some-profile"
でもset -eux
印刷されるから
+ java -jar /opt/someJar.jar --server.port=1234 --spring.profiles.active=some-profile
それが私が本当に欲しいものです。
何らかの理由で十分な情報を提供できない場合は、追加情報を提供できます。私が達成しようとしているのは、これがなぜこれを行うのか、そして/bin/sh
そのような単純なスクリプトでそれを使用する方法を理解することです。
答え1
Stéphaneは$@
これを通常のシェルで配列として使用すると述べました。 1つの方法は次のとおりです。
#!/bin/sh
set -eux
set -- # clear cmdline params
if [ "$DEBUG" = "true" ]; then
set -- "-Xdebug" "-Xrunjdwp:transport=dt_socket,server=y,suspend=$SUSPEND,address=$DEBUG_PORT"
fi
# specify the jar file
set -- "$@" -jar /opt/someJar.jar
# add the port and profile
set -- "$@" "--server.port=${SERVER_PORT}"
set -- "$@" "--spring.profiles.active=${PROFILES}"
# and run it
java "$@"
答え2
sh
配列がありません("$@"
位置パラメータ配列を除く)。
存在する:
java "${debug:-}"-jar /opt/someJar.jar "${all:-}"
java
(自分に加えて)3つのパラメータのみが渡されますjava
。
2つのパラメータを渡す場合、最後のパラメータには--server.port=1234 --spring.profiles.active=some-profile
スペースなどの内容が--server.port=1234
含まれます--spring.profiles.active=some-profile
。
ㅏスカラー(大大量に)変数には、 1つの値$all
しかsh
含めることができません。
代わりに、"$@"
配列を次のように使用できます。グレンが見えた(私はまた混合し、$IFS
非常noglob
に汚れたものが好きです)またはシェルで話すことができます分ける変数の内容を delimiter に設定して拡張し、パラメータ拡張$IFS
を引用符なしで残します(ワイルドカードを無効にした後、デフォルトでは引用符なしのパラメータ拡張でもワイルドカードが実行されるため)。
の場合、$IFS
パラメータに表示できない文字を選択する必要があります。パラメータを空白にするには、その文字をSPC、TAB、NLにすることはできません(3文字はすべてデフォルト値になっています$IFS
)。
しかし、あなたの場合は、空のインスタンスがnullの場合(空の引数ではなく)、その引数が発生しないことを$serv
望むように見えるので、空白がより良いアイデアになる可能性があります。 NLはあなたの主張に見られる可能性が低いため、良い選択肢になる可能性があります。$serv
$IFS
serv="--server.port=${SERVER_PORT}"
prop="--spring.profiles.active=${PROFILES}"
IFS="
" # newline character only
all="${serv:-}${IFS}${prop:-}"
set -o noglob # disable glob
java ... /opt/someJar.jar $all
についても同様のことを行う必要があります$debug
。
set -o noglob
パラメータにワイルドカード、中括弧、またはバックスラッシュが含まれていないことを保証できる場合は、この手順をスキップできます。
xtrace
シェルの出力は若干誤解を招くおそれがあります。 SPC文字で区切られた生出力を介してコマンドに渡された引数のリストを表します。これは、パラメータのSPC文字とパラメータxtrace
を区別するために使用される出力文字を区別できないことを意味します。
いくつかの他のシェルは、そのようなあいまいさが存在するとき引数の周りに引用符を出力するので、より便利です。
set -x; printf "<%s>\n" foo "bar baz"
複数の異なるシェル解析の出力を比較します。
$ dash -c 'set -x; printf "<%s>\n" foo "bar baz"'
+ printf <%s>\n foo bar baz
<foo>
<bar baz>
$ bosh -c 'set -x; printf "<%s>\n" foo "bar baz"'
+ printf <%s>\n foo bar baz
<foo>
<bar baz>
$ bash -c 'set -x; printf "<%s>\n" foo "bar baz"'
+ printf '<%s>\n' foo 'bar baz'
<foo>
<bar baz>
$ ksh -c 'set -x; printf "<%s>\n" foo "bar baz"'
+ printf '<%s>\n' foo 'bar baz'
<foo>
<bar baz>
あなたのアイテムは/カテゴリsh
に属しているようです。 xtrace出力が3つの引数をどのように渡すかを考えるようにしてください。実際には2つの引数とを渡しています。dash
bosh
+ printf <%s>\n foo bar baz
printf
foo
bar
baz
foo
bar baz