변수에 저장된 일부 명령을 호출하는 올바른 방법은 무엇입니까?
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에서 테스트되었습니다.
답변
넣어야 할 것 같아요
`
(백틱) 변수 주변의 기호.