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


답변:


95

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

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

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

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

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

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

6
eval "$cmd"글 을 쓰지 않고 하는 방법 eval? $($cmd)? ${$cmd}?
Steven Lu

2
@StevenLu, 그것들 중 어느 것도 동등하지 않습니다.-의도적으로 : eval연산은 데이터를 구문으로 구문 분석합니다. 따라서 보안에 매우 민감하며 암시 적으로 수행하는 것은 매우 나쁜 형식입니다.
Charles Duffy

5

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


오판 일뿐입니다. "grep 예외"여야합니다.
Volodymyr Bezuglyy

그런 다음 $ cmd 자체가 아닌 eval을 사용하십시오. 아마도 작동하지 않을 것입니다. 이것이 eval이 의도 한
바입니다

0

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

두 번째 방법은 유연하지 않은 명령을 실행하려는 경우 유용합니다.
for i in {$a..$b}
변수를 허용하지 않기 때문에 형식 루프가 작동하지 않습니다.
이 경우 bash 또는 eval에 대한 파이프가 해결 방법입니다.

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


-4

넣어야 할 것 같아요

`

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


4
이것은 명령의 출력을 실행합니다. 예를 들어 ls -l의 경우 "total"command not found "와 같은 메시지가 생성됩니다 (total ...은 ls -l 출력의 일부이기 때문입니다. 예). 당신이 원하는 NOT 것.
Henno Brandsma에게
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.