[shell] 변수에 저장된 명령을 실행하는 방법은 무엇입니까?

변수에 저장된 일부 명령을 호출하는 올바른 방법은 무엇입니까?
1과 2 사이에 차이점이 있습니까?

#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"



답변

Unix 셸은 실행하기 전에 각 입력 라인에서 일련의 변환을 수행합니다. 대부분의 쉘의 경우 다음과 같이 보입니다 ( bash맨 페이지 에서 가져옴).

  • 초기 단어 분할
  • 중괄호 확장
  • 물결표 확장
  • 매개 변수, 변수 및 산술 확장
  • 명령 대체
  • 2 차 단어 분할
  • 경로 확장 (일명 globbing)
  • 견적 제거

$cmd직접 사용 하면 매개 변수 확장 단계에서 명령으로 대체되고 다음의 모든 변환이 수행됩니다.

를 사용 eval "$cmd"하면 따옴표 제거 단계까지 아무 작업도 수행되지 않습니다. 여기서는있는 $cmd그대로 반환되고 eval실행 전에 전체 체인을 다시 실행하는 기능이 있는에 매개 변수로 전달됩니다 .

따라서 기본적으로 대부분의 경우 동일하며 명령이 매개 변수 확장까지 변환 단계를 사용할 때 다릅니다. 예를 들어 중괄호 확장 사용 :

$ cmd="echo foo{bar,baz}"
$ $cmd
foo{bar,baz}
$ eval "$cmd"
foobar foobaz


답변

eval $cmd
우리가 할 때 cmd="ls -l"(대화식 및 스크립트에서) 그렇게하면 원하는 결과를 얻습니다. 귀하의 경우 패턴이없는 grep이있는 파이프가 있으므로 grep 부분이 오류 메시지와 함께 실패합니다. 그냥 $cmd은 “명령을 찾을 수 없습니다”(또는 일부 등) 메시지를 생성합니다. 따라서 eval을 사용하고 오류 메시지를 생성하는 명령이 아닌 완료된 명령을 사용하십시오.


답변

$cmd변수를 명령 줄에서 실행되는 값으로 바꿉니다.
eval "$cmd"명령 줄에서 결과 값을 실행하기 전에 변수 확장 및 명령 대체를 수행합니다.

두 번째 방법은 유연하지 않은 명령을 실행하려는 경우 유용합니다.

for i in {$a..$b}
변수를 허용하지 않기 때문에 형식 루프가 작동하지 않습니다.
이 경우 bash 또는 eval에 대한 파이프가 해결 방법입니다.

Mac OSX 10.6.8, Bash 3.2.48에서 테스트되었습니다.


답변

넣어야 할 것 같아요

`

(백틱) 변수 주변의 기호.


답변