XML 파일을 생성한 다음 Perl 스크립트를 실행하여 일련의 매개변수를 전달하는 스크립트가 있습니다. 이것은 키 코드입니다:
CMD="./dnscurl.pl --keyname $KEYNAME -- -X POST -H \"Content-Type: text/xml; charset=UTF-8\" --upload-file /tmp/file.xml https://route53.amazonaws.com/2010-10-01/hostedzone/$HZID/rrset"
echo "Executing..."
echo $CMD
RESULT=`$CMD`
실행하면 -H 매개변수가 dnscurl.pl 스크립트로 전송된 후 포함된 매개변수에 문제가 발생한 것으로 나타났습니다.
컬: (6) 호스트 '텍스트'를 구문 분석할 수 없습니다.
그러나 내가 에코한 정확한 명령을 얻을 수 있으며 쉘 프롬프트에서 이를 실행하면 스크립트가 올바르게 실행됩니다. 백틱과 함께 RESULT=를 사용하여 실행하면 $CMD
매개변수가 "Content-Type: etc..." 주위의 큰따옴표를 통해 전달되지 않는 것 같습니다.
내가 실행 중인 명령은 다음과 같습니다(키 이름과 호스트 ID 매개변수만 변경됨).
./dnscurl.pl --keyname mykey -- -X POST -H "Content-Type: text/xml; charset=UTF-8" --upload-file /tmp/file.xml https://route53.amazonaws.com/2010-10-01/hostedzone/ZZZZZZZ/rrset
제가 궁금한 점 중 하나는 "--"를 사용하는 것입니다. 나는 이것이 dnscurl.pl 스크립트에 의해 구체적으로 처리된다는 것을 알고 있지만 그것이 전달되는 이유는 분명하지 않습니다. 위치 매개변수 처리가 우회되었기 때문인가요? 이 스크립트는 3가지 다른 사용 사례를 처리하도록 작성되었습니다. 나는 이것이 관련이 없다고 생각하지만 완전성을 위해 이 스크립트는 AWS의 Route 53 Rest API를 호출하는 데 사용됩니다.
답변1
인용이 잘못되었습니다. 따옴표 없이 작성하면 $CMD
값은 $CMD
공백의 각 시퀀스에서 "단어"로 분할되고(단어에는 구두점을 포함하여 공백이 아닌 문자가 포함될 수 있음) 각 단어가 와일드카드로 확장됩니다(즉, 와일드카드 확장 ). 특히 값의 따옴표는 CMD
변경되지 않습니다. 따옴표는 쉘 스크립트 구문에서는 의미가 있지만 변수 대체에서는 의미가 없습니다. 그 후 첫 번째 단어는 실행할 명령의 이름이 되고, 그 다음 단어는 명령의 인수가 됩니다.
귀하의 예에서 $KEYNAME
is somekeyname
및 $HZID
is 라고 가정하면 somehzid
명령과 매개 변수는 다음과 같습니다.
./dnscurl.pl
--keyname
$KEYNAME
--
-X
POST
-H
"Content-Type:
text/xml;
charset=UTF-8"
--upload-file
/tmp/file.xml
https://route53.amazonaws.com/2010-10-01/hostedzone/somehzid/rrset
매개변수 는 text/xml;
옵션이 아닌 첫 번째 매개변수로 나타납니다. Perl 스크립트는 해당 매개변수를 curl
매개변수 목록에 전달하며 --
귀하의 질문과 아무 관련이 없습니다.
명령줄을 변수에 채울 수 없습니다. (단순) 변수는 잘못된 도구입니다. 변수에는 문자열이 포함되어 있지만 명령줄은 문자열(명령 및 해당 인수) 목록입니다. 명령 이름과 해당 매개변수를 배열 변수에 채울 수 있습니다.
CMD=(./dnscurl.pl --keyname "$KEYNAME" --
-X POST -H "Content-Type: text/xml; charset=UTF-8"
--upload-file /tmp/file.xml
"https://route53.amazonaws.com/2010-10-01/hostedzone/$HZID/rrset")
RESULT=$("${CMD[@]}")
이상한 구문처럼 보이는 것은 "${CMD[@]}"
배열 변수를 CMD
배열의 단어 목록으로 확장합니다. 큰따옴표는 배열 내의 단어 확장을 방지하며 [@]
역사적 이유로 배열을 확장하려고 한다는 것을 쉘에 알리는 데 필요합니다.
나중에 사용하기 위해 명령줄이나 임의의 셸 조각을 기억하는 또 다른 방법은 함수입니다.
cmd () {
./dnscurl.pl --keyname "$KEYNAME" -- \
-X POST -H "Content-Type: text/xml; charset=UTF-8" \
--upload-file /tmp/file.xml \
"https://route53.amazonaws.com/2010-10-01/hostedzone/$HZID/rrset"
}
RESULT=$(cmd)
보다 정확하게는 의 값에 따라 IFS
.