2009-09-04 3 views
2

변수에 명령에 인수를 저장합니다. 내가 원하는 마지막 명령은 다음과 같습니다 여기 인용 부호는 bash 변수 내에서 존중하지 않습니다.

mock -r myconfig --define "debug_package %{nil}" --resultdir results --rebuild mypackage.src.rpm 

내 시도입니다 :

set -x # for debugging 

RESULTDIR=results 
MOCK_CONFIG="myconfig" 
MOCK_ARGS="-r $MOCK_CONFIG --define \"debug_package %{nil}\" --resultdir $RESULTDIR" 
cmd="mock $MOCK_ARGS --rebuild mypackage.src.rpm" 
$cmd 

결과는 다음과 같습니다 당신이 볼 수 있듯이, --define 매개 변수에 인수가 존재하지 않는

+ RESULTDIR=results 
+ MOCK_CONFIG=myconfig 
+ MOCK_ARGS='-r myconfig --define "debug_package %{nil}" --resultdir results' 
+ cmd='mock -r myconfig --define "debug_package %{nil}" --resultdir results --rebuild mypackage.src.rpm' 
+ mock -r myconfig --define '"debug_package' '%{nil}"' --resultdir results --rebuild mypackage.src.rpm 
ERROR: Bad option for '--define' ("debug_package). Use --define 'macro expr' 

적절하게 인용했다. --define 나는 그것을 단지 불완전한 debug_package으로 전달하고 있다고 생각합니다.

MOCK_ARGS을 정의 할 때 여러 가지 변형을 시도했으며 심지어 debug_package%{nil} 사이의 공백을 이스케이프 처리하려고했습니다.

이 인수 목록을 작성하고이 스크립트에서 명령을 실행할 수있는 따옴표 및/또는 이스케이프 조합은 무엇입니까?

EDIT :

I 가변 명령의 결과를 기억하고있어 그 이유는 그것이 어떤 기록을하는 함수로 전달되는 끝 때문에, 그 명령을 실행한다.

또한 나는 변수 대신 배열을 사용해야한다고 제안하는 this FAQ을 발견했습니다. 나는 배열을 실험하기 시작했지만 지금까지는 작동하는 해결책이 없다.

+0

이것은 http://stackoverflow.com/questions/954390/echo-nested-quotation-marks-in-tcsh –

+0

의 복제본처럼 보입니다. http://stackoverflow.com/questions/954390/echo- nested-quotation-marks-in-tcsh는 나를 위해 작동하지 않습니다. –

+0

[bash 명령을 따옴표와 별표가있는 문자열로 저장하는 방법] (http://stackoverflow.com/questions/2005192/how-to-execute-a-bash-command-stored-as-a) -string-with-quotes-and-asterisk) –

답변

4

배열이 같은 것들에 갈 수있는 방법입니다.여기에 내가 무엇을 최대 온의 : $ *는 (로그 명령에 전달하기에 적합) 공백으로 구분 된 모든 매개 변수로 확장

log_and_run() { 
    echo "$(date): running command: $*" 
    "[email protected]" 
    echo "$1 completed with status $?" 
} 

RESULTDIR=results 
MOCK_CONFIG="myconfig" 
MOCK_ARGS=(-r "$MOCK_CONFIG" --define "debug_package %{nil}" --resultdir "$RESULTDIR") 
cmd=(mock "${MOCK_ARGS[@]}" --rebuild mypackage.src.rpm) 
log_and_run "${cmd[@]}" 
# could also use: log_and_run mock "${MOCK_ARGS[@]}" --rebuild mypackage.src.rpm 

참고; "$ @"는 모든 매개 변수를 별도의 단어로 확장합니다 (log_and_run에서 사용되는 것처럼 첫 번째 매개 변수는 실행 명령으로 처리되고 나머지 매개 변수는 매개 변수로 사용됩니다). 비슷하게 "$ {MOCK_ARGS [@]}"는 MOCK_ARGS의 모든 요소를 ​​공백을 포함하고 있는지 여부에 관계없이 별도의 단어로 확장합니다 (따라서 MOCK_ARGS의 각 요소는 따옴표 해석 혼동이없는 cmd의 요소가됩니다).

또한 MOCK_CONFIG 및 RESULTDIR의 확장을 인용했습니다. 이것은 공백을 포함하지 않기 때문에 여기서는 필요하지 않지만 공백을 포함하는 경우에 들어가기에 좋은 습관입니다 (예를 들어 외부에서 스크립트로 전달되는 경우? 공백을 포함 할 수 있다고 가정해야합니다) .

현재 매개 변수를 함수에 전달해야하는 경우 (예 : 파일 이름의 예를 사용하여 로그온) array slicing을 사용하여 이후 매개 변수 만 분리하여 로그/실행 :

log_and_run() { 
    echo "$(date): running command ${*:2}" >>"$1" 
    "${@:2}" 
    echo "$2 completed with status $?" >>"$1" 
} 
#... 
log_and_run test.log "${cmd[@]}" 

부록을 : 당신이 로그에 공간을 포함하는 매개 변수를 인용하려는 경우, 당신은 "수동으로"로그 문자열을 구성하고 당신이 무엇을 원하는 인용 할 수 있습니다. 예를 들면 다음과 같습니다.

매개 변수와 공백 매개 변수의 공백은 처리하지만 매개 변수 안의 큰 따옴표는 처리하지 않습니다. 이 "올바른"일을 임의로 복잡한 얻을 수 있습니다 ...

또한 내가 log_cmd 문자열을 구성하는 방법, 그것은 선행 공백; 위에서 echo 명령에서 공백을 생략함으로써 이것을 처리했습니다. 실제로 공간을 자르려면 "${log_cmd# }"을 사용하십시오.

+0

고마워요,이게 내 문제를 해결합니다! 천재의 스트로크는 완전한 모의 명령을 배열로 만드는 것이었다. 이것은'$ *'및/또는'$ @ '대신에'$ 1'을 사용하여 명령을 기록하고 실행하는'log_and_run()'함수의 리팩토링으로 이어졌습니다. ''debug_package % {nil} ''주위의 따옴표를 로그에 표시 할 수는 없지만 살 수있는 사소한 세부 사항입니다. –

4

쉘 스크립트는 비참 할 수 있습니다. 대부분의 경우 cmd="blah $blah";$cmdblah $blah과 다릅니다. $ cmd 대신 eval $cmd을 시도해보십시오.

모의 대신이 펄 스크립트를 호출 시도 :

#!/usr/bin/perl 
print join("\n",@ARGV),"\n"; 

당신은 인수 목록이 실제로 무엇을보고 놀랄 수 있습니다 : 내 생각이지만

-r 
myconfig 
--define 
"debug_package 
%{nil}" 
--resultdir 
results 
--rebuild 
mypackage.src.rpm 

은 "-x 설정"출력 작은 따옴표로 이것을 보여 주려고합니다. 내가 최근에 배운

하나의 좋은 트릭은

function f { 
    echo "[email protected]" 
} 

이 실제로 제대로 F에 위치 인수를 전달한다는 것입니다 ( $*하지 않습니다).

그것은 "평가"처럼 보이는 당신은 아마 무슨 의도 제공 :

set -x # for debugging 
RESULTDIR=results 
MOCK_CONFIG="myconfig" 
MOCK_ARGS="-r $MOCK_CONFIG "'--define "debug_package %{nil}" --resultdir '"$RESULTDIR" 
cmd="mock $MOCK_ARGS --rebuild mypackage.src.rpm" 
echo $cmd 
eval $cmd 

출력 :

+ echo mock -r myconfig --define '"debug_package' '%{nil}"' --resultdir results --rebuild mypackage.src.rpm 
mock -r myconfig --define "debug_package %{nil}" --resultdir results --rebuild mypackage.src.rpm 
+ eval mock -r myconfig --define '"debug_package' '%{nil}"' --resultdir results --rebuild mypackage.src.rpm 
++ mock -r myconfig --define 'debug_package %{nil}' --resultdir results --rebuild mypackage.src.rpm 
-r 
myconfig 
--define 
debug_package %{nil} 
--resultdir 
results 
--rebuild 
mypackage.src.rpm 
+2

감사 - 평가판이 나를위한 빠른 수정 프로그램이었습니다. –