중복일 수도 있지만 문제가 해결되지 않은 원래 질문에 대한 답변을 찾았습니다.
질문을 다시 작성했습니다.
이 Java 애플리케이션이 있습니다.
public static void main(final String[] args) {
System.out.println("DEBUG: arguments passed to the main - " + Arrays.toString(args));
System.exit(new TaskRunner().run(args));
}
두 개의 매개변수를 사용하여 코드를 직접 호출하는 경우:
$ nohup ${JAVA_HOME}/bin/java -cp /opt/fxudply/fxcal-client-jar/current/lib:/opt/fxudply/fxcal-client-jar/current/lib/*:/opt/fxudply/fxcal-config/current/wib-config:/opt/fxudply/fxcal-config/current/wib-config/* wib.runner.TaskRunner -taskExtRef "QUOTES_UPLOAD IPV - EOD Rates Input - Commodities Volatilities" > /opt/sw/calypso/logs/taskrunner/log.direct.log 2>&1
그것은 인쇄한다
[TaskRunner] DEBUG: : arguments passed to the main - [-taskExtRef, QUOTES_UPLOAD IPV - EOD Rates Input - Commodities Volatilities]
이것이 바로 제가 기대했던 것입니다. 하지만 이 쉘 스크립트( )를 작성하면 startScheduledTask.sh
:
NOW_DATE=`date '+%Y%m%d%H%M%S'`
nohup ${JAVA_HOME}/bin/java -cp some:classpath:values package.name.classname "$@" > /opt/random/path/tplogs/classname/${aVariableLogName}.${NOW_DATE}.log 2>&1
다음과 같이 실행하십시오.
$ ./startScheduledTask.sh -taskExtRef "QUOTES_UPLOAD IPV - EOD Rates Input - Commodities Volatilities" &
나는 다음과 같은 결과를 얻습니다.
[TaskRunner] DEBUG: : arguments passed to the main - [-taskExtRef, QUOTES_UPLOAD, IPV, -, EOD, Rates, Input, -, Commodities, Volatilities]
(즉, 두 번째 인수는 8개의 공백을 포함하므로 9개의 인수로 나뉩니다.) 그래서 대본에 문제가 있는 것 같아요.
어떻게 해결할 수 있나요?
답변1
쉘은 명령줄을 구문 분석할 때 따옴표를 제거하지만 그것이 암시하는 텍스트 구조는 기억합니다. (이것은 지나치게 단순화한 것입니다.큰 타격(1)또는쉘 명령 언어자세한 내용을 알아보세요. ) 예를 들어 명령줄 입력
-blah apple -secondfruit "green banana" -some more
쉘이 6개의 단어 또는 토큰을 인식하도록 합니다.
-blah
apple
-secondfruit
green banana
-some
more
메모리에 저장될 거예요
-blahⓧappleⓧ-secondfruitⓧgreen bananaⓧ-someⓧmoreⓧ
이는 ⓧ
널 바이트를 나타냅니다. 때로는 다음과 같이 표시되거나 보고됩니다.
-blah apple -secondfruit green banana -some more
따라서 따옴표가 무시되고 7개의 단어만 있다고 생각할 수도 있지만 실제로는 원하는 것이 이미 있습니다.
노트:
위 수식에서 는
ⓧ
널 바이트를 나타냅니다. 제가 여기서 설명하는 것은기준쉘 매개변수 구문 분석 처리. 당신이 입력하면ls -l fruit.sh "I came here for an argument" startScheduledTask.sh
/bin/ls
문자열을 사용하여 프로그램 호출lsⓧ-lⓧfruit.shⓧI came here for an argumentⓧstartScheduledTask.shⓧ
기억상으로는 이렇게 해석된다.
- 인수[0] =
ls
- 인수[1] =
-l
- 인수[2] =
fruit.sh
- 인수[3] =
I came here for an argument
- 인수[4] =
startScheduledTask.sh
이것정확히 같은 과정당신이라면 그런 일이 일어날 것입니다
java
기본 대화형 셸에 직접 명령을 입력합니다.java
쉘 스크립트에서 명령을 실행 하거나./startScheduledTask.sh
기본 대화형 셸에 직접 명령을 입력하여 셸 스크립트를 실행합니다.그래서이것은 문제가 되지 않습니다. 인수가 널 문자로 구분된 인수를 처리할 수 없는 모든 프로그램 유닉스와 리눅스에서는 작동하지 않습니다.
긴 이야기 짧게
첫 번째 명령이 정확합니다. "$@"
원하는 것을 제공합니다. 이는 쉘 스크립트가 호출하는 프로그램에 인수를 전달하는 올바른 방법입니다. 인수를 반복하기 위해 프로그램에 디버깅 코드를 추가하고 각 인수를 새 줄 및/또는 괄호 안에 인쇄하는 경우(모두 한 줄에 표시되지 않고 공백으로만 구분됨) "$@"
프로그램에 6개의 매개 변수가 표시됩니다.
음, 더 있습니다:
클래스 경로에는 별표(
*
s) 안에요? 정말? 저는 Java를 처음 접했지만 이것이 이상하게 보입니다. 시스템이 이 작업을 올바르게 수행하고 있는지 다시 확인하십시오. 그러나 별표가 있는 클래스 경로를 "직접"(즉, 기본 쉘, 기본 대화형 쉘, 로그인 쉘에 직접) 입력하면 제대로 작동하는 것입니다.아마도문제가 아니다.하지만 어쨌든 저를 유머러스하게 표현하고 해당 문자열을 따옴표로 묶어주세요.
귀하의 질문이 너무 복잡합니다. 비행기를 만들 때 비행기 전체를 만든 다음 날리려고 시도하는 것이 아닙니다. 그러면 비행기가 날지 않을 때 뒤로 물러서서 "비행기에 무슨 문제가 있나요?"라고 묻지 않습니다. 아니, 덩어리로 테스트합니다. 단순화할 필요가 있습니다.
- 백그라운드에서 실행을 중지하세요.
- 말 하지마
nohup
. - 출력 리디렉션을 중지합니다.
- 질문에 42자의 긴 쉘 프롬프트를 표시하지 마십시오.
- 당신의 문제는~에 대한매개변수 하나에는 공백이 포함되어 있으므로 제거하지 마세요. 단, 길이가 60자이고 공백이 8개일 필요는 없습니다.
green banana
는엄청난테스트 값. - 프로그램의 매개변수를 사용해 보세요.아니요에 의해. . . 시작
-
(스프린트). new TaskRunner().run(args)
DEBUG 및System.exit(0);
.
어느 것도 아니다~해야 한다변화를 만들다. 하지만 주의가 산만해지고 중요한 것이 무엇인지 파악하기 어려울 수 있습니다. 최소한의 테스트 구성으로 문제를 입증할 수 있다면 문제와 관련된 다른 모든 것을 배제할 수 있습니다. 그러나 관련 없는 내용을 삭제한 후 문제가 해결된다면 다음 중 하나에 의해 문제가 발생한 것일 수 있습니다.
또한 질문에 가짜/테스트 데이터와 실제 데이터(예: 과일 및 작업)를 혼합하지 마십시오.
다음 스크립트를 작성하세요(라고 부르세요
fruity.sh
).#!/bin/sh # classpath CP="/opt/fxudply/fxcal-client-jar/current/lib:/opt/fxudply/fxcal-client-jar/current/lib/*:/opt/fxudply/fxcal-config/current/wib-config:/opt/fxudply/fxcal-config/current/wib-config/*" # package.name.classname PC=wib.runner.TaskRunner "$JAVA_HOME"/bin/java -cp "$CP" "$PC" "$@"
그리고 달리다
./fruity.sh taskExtRef "green banana"
디버깅이 말한다면
…[taskExtRef, green banana]
잘
"$@"
작동하는데 문제는 스크립트의 다른 곳에 있습니다. 그것을 찾아보십시오. 한 번에 하나씩 변경하고 동작이 어떻게 바뀌는지 확인하세요. 당신이 그것을 알아낼 수 없다면, 우리가 당신을 도울 수 있을 것입니다. 그러나 당신이 우리에게 스크립트의 일부를 보여줄 경우에만 가능합니다.~로 이어지다질문.하지만 디버깅이 말한다면
…[taskExtRef, green, banana]
그렇다면 우리에게 알려주세요.