나중에 사용할 때가 아니라 문자열을 만들 때 문자열의 Bash 명령이 실행됩니다.


10

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

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

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

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

답변:


8

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


고마워, $(...)Hauke가 제안한대로 사용하려고 했지만 백 슬래시가 핵심입니다.
Ricky

도움이 된 것을 기쁘게 생각합니다. 그러나 여기서 중요한 eval점은 명령을 둘러싸 기 위해 큰 따옴표 ( ) 대신 $작은 따옴표 ( ') 를 이스케이프 처리하지 않고 사용하여 동일한 작업을 수행 할 수 있다는 것 "입니다.
daBeamer

이제 Huake의 제안과 마찬가지로 lftp 프로그램에서 이것을 사용하려고하면 echo가 단순히 명령을 인쇄하면 실제로 실행되지 않습니다. 보다 구체적인 도움을 받으려면 메일 링리스트를 시도해야 할 수도 있습니다.
Ricky

실행하려는 명령은 무엇입니까? echo지연 실행 중첩 명령의 출력을 포함하여 내용이 포함 된 문자열 을 원한다는 인상을 받았습니다 .
daBeamer

1
@Ricky @HaukeLaging의 모든 요점에 동의해야합니다. 에 코드를 빼면 코드 echo가 작동하지 않으며 eval문자열이 아닙니다. 우리에게 더 적절한 모범이 있다면, 우리는 도울 수 있습니다.
daBeamer

6

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

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

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


빠른 답변 Hauke에 감사드립니다. 불행히도 백틱을 권장으로 대체하면 $(...)동일한 결과가 생성됩니다. 내 문자열이 정의되면 쉘이이를 실행합니다.
Ricky

@Ricky 대체 제안이 아니 었습니다. 당신은 사용해야 $()하지만 어쨌든 작은 따옴표가 필요합니다.
Hauke ​​Laging

그래서 그 캐릭터들의 조합이 내가 추구하는 것을 달성하지 못합니까?
Ricky

@Ricky "작은 따옴표가 필요하다"에 대해 이해하기 어려운 것은 무엇입니까? 당신은 분명히 시도조차하지 않습니다.
Hauke ​​Laging

실제로 나는했지만 작은 따옴표를 사용하면 에코는 해당 줄의 모든 것을 일반 문자열로 인쇄합니다. 예를 제공하는 것이 어려운 점은 무엇입니까?
Ricky
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.