몇 가지 간단한 플래그를 사용하여 실행 스크립트를 만들려고 합니다./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:-}"
이제 설명할 수 없고 왜 그런 일이 발생하는지 Google에서 찾을 수 없는 몇 가지 문제를 발견했습니다.
"${debug:-}"-jar
자리가 없으니 참고하세요 . 공백을 넣으면 "java가 메인 클래스를 찾거나 로드할 수 없습니다."라는 메시지와 함께 응용 프로그램이 중단됩니다. 공간을 제거하면 예상대로 작동합니다.- 두 개의 변수
serv
와prop
. 이 두 가지를 java 명령 끝에 넣으면"${serv:-}" "${prop:-}"
이 두 매개변수가 애플리케이션에서 별도로 전달됩니다. 그러나"${all:-}"
Java의 예외에서 증가시키면 이 둘이 서로 연결되어 있는 것을 볼 수 있습니다.
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은 $@
이를 일반 쉘에서 배열로 사용한다고 언급했습니다. 한 가지 방법은 다음과 같습니다.
#!/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
.
두 개의 매개변수를 전달하려는 경우 마지막 매개변수에는 --server.port=1234 --spring.profiles.active=some-profile
공백과 같은 내용이 --server.port=1234
포함 됩니다 --spring.profiles.active=some-profile
.
ㅏ스칼라(대대량으로) 변수는 $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개의 인수를 전달한다고 생각하게 만드는지 확인하세요 . 실제로 는 두 개의 인수인 및 를 전달하고 있습니다 .dash
bosh
+ printf <%s>\n foo bar baz
printf
foo
bar
baz
foo
bar baz