나중에 사용할 때가 아니라 문자열을 만들 때 문자열의 Bash 명령이 실행됩니다. 구분 ;). for var in

저는 쉘 스크립팅을 처음 했지만 lftp 프로그램을 사용하는 스크립트를 거의 완성했습니다 . 문제가있는 스크립트 부분은 긴 문자열을 만들 때입니다 (로 구분 ;).

for var in something
do
    ...
    commands_to_run+="echo Result is `tail -n 1 $somefile`;"
done

내가 주목하는 것은 tailfor 루프가 반복 될 때 백틱으로 래핑 된 프로그램이 실행되고 있지만 나중에 스크립트에서 명령 문자열을 호출 할 때는 실행되지 않는다는 것입니다.

불행히도 $ somefile의 내용은이 단계에서 검사 할 준비가되지 않았습니다. 문자열을 만들 때가 아니라 필요할 때 명령을 실행하려면 어떻게해야합니까?



답변

이것은 조금 까다 롭습니다. 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대부분의 상황에서 사용하는 습관을 들이지 마십시오 . 그러나 이것을 피하는 좋은 방법을 모르는 사람들 중 하나입니다. 잘하면 이것이 도움이됩니다. 행운을 빕니다!


답변

인용에는 몇 가지 수준이 있습니다. 큰 따옴표 ( "...") 보호 공백 및 여러 특수 문자 ( ~, &, |, ;, …)하지만, 매개 변수 확장 및 명령 대체를 방지하지 않습니다.

'“위험한”문자 앞에 작은 따옴표 ( ) 또는 백 슬래시 가 필요합니다 .

일반적으로 : $(tail ...)백틱 대신에 사용을 고려해야 합니다. 백틱은 더 오래된 표준이지만 $()대부분의 사람들에게 문제를 일으키지 않는 너무 오래된 것에 대해 이야기하고 있습니다. 새 버전은 읽기 쉽고 중첩 될 수 있습니다. sx의 형식 문제는 물론 …


답변