저는 쉘 스크립팅을 처음 접했지만 익스플로잇을 거의 완료했습니다.FTP 프로그램. 스크립트에서 문제가 있는 부분은 긴 명령 목록( 로 구분 ;
)을 생성할 때입니다.
for var in something
do
...
commands_to_run+="echo Result is `tail -n 1 $somefile`;"
done
내가 알아차린 것은 tail
스크립트에서 나중에 명령 문자열을 호출할 때가 아니라 for 루프가 반복될 때 프로그램(백틱으로 묶음)이 실행된다는 것입니다.
불행하게도 이 단계에서는 $somefile의 내용을 검사할 준비가 되지 않았습니다. 문자열이 생성될 때가 아니라 필요할 때 명령이 실행되도록 하려면 어떻게 해야 합니까?
답변1
이건 좀 까다롭습니다. Hauke가 제공한 정보는 정확합니다. 사용 사례에 따라 분석하면 됩니다.
가장 간단한 방법은 변수 정의가 정의에 포함된 명령을 $()
실행하지 않도록 이스케이프 구문을 사용하는 것입니다 . 중첩된 명령이 실제로 실행될 때 셸에서 $
최종 결과를 다시 평가(통과)해야 한다는 점에 유의하는 것이 중요합니다 .$()
eval
예제를 보는 것이 훨씬 쉽기 때문에 다음 예제를 보면 올바른 방향으로 갈 수 있을 것입니다.
for((i=0;i<10;i++)); do
date +%s.%N # Print a timestamp (in format seconds.nanoseconds)
test="echo \$(date +%s.%N)" # Save a command to do the same
sleep 1 # Sleep for a second
eval "$test" # Evaluate the command saved in variable 'test'
echo # Print a new line before the next iteration
done
다음은 위 예제의 샘플 출력입니다(1회 반복으로 잘림).
1398832186.133661344
1398832187.139076728
각 루프의 두 번째 타임스탬프는 첫 번째 타임스탬프 이후 약 1초라는 것을 알 수 있습니다. 반대로 정의 $
에서 이스케이프 test
및 제거 없이 동일한 테스트를 수행하면 eval
두 타임스탬프가 거의 일치합니다.
대부분의 상황에서 그것을 사용하는 습관을 들이지 마십시오 eval
. 그러나 이것은 그것을 피하는 좋은 방법을 모르는 상황 중 하나입니다. 도움이 되었기를 바랍니다. 행운을 빌어요!
답변2
인용에는 여러 수준이 있습니다. 큰따옴표( "..."
)는 공백과 여러 특수 문자( ~
, &
, |
, ;
, ...)를 보호하지만 매개변수 확장 및 명령 대체를 방지하지는 않습니다.
'
"위험한" 문자 앞에 작은따옴표( ) 또는 백슬래시를 추가 해야 합니다 .
일반적으로 백틱을 대신 사용하는 것을 고려해야 합니다 $(tail ...)
. 백틱은 오래된 표준이지만 우리는 $()
대부분의 사람들에게 문제를 일으키지 않는 매우 오래된 표준에 대해 이야기하고 있습니다. 새 버전은 읽기가 더 쉽고 중첩될 수 있습니다. sx의 형식 문제는 말할 것도 없고...