2014-10-03 3 views
0

나는 다음과 같은 명령을 실행하기 위해 노력하고있어 : 두 번째 명령 전에 "-x 설정 사용"배쉬 토큰 화 인용 된 문자열

ls: 'my: No such file or directory 
ls: dir': No such file or directory 

:

mkdir 'my dir' 
CMD="ls 'my dir'" 
RESULT=$($CMD) 

이 결과를 실제로 발급되는 명령은 다음과 같습니다.

++ ls ''\''my' 'dir'\''' 

이것은 분명히 내가 아는 사람이었던 것으로부터 추상화 된 것입니다. 혼자하는 것을 시도; 이 코드는 그 자체로는 어떤 목적도 제공하지 않습니다. 하지만 내 질문은 왜 bash는 이런 인용 문자열을 토큰 화하고 어떻게 멈출 수 있습니까?

+2

BashFAQ # 50 : http://mywiki.wooledge.org/BashFAQ/050을 참조하십시오. –

+0

감사합니다. 매우 도움이됩니다. – cameronhimself

+0

[BashFAQ # 48] (http://mywiki.wooledge.org/BashFAQ/048)도 참조하십시오. GreyCat이 말했듯이, "eval"은 흔히 "악마"의 철자법 오류입니다. :) –

답변

3

(거의) 모든 언어 코드와 데이터를 분리 :

args="1, 2" 
myfunc(args) != myfunc(1, 2) 

동일 bash에서는 사실입니다. 리터럴 문자열에 작은 따옴표를 써도 bash는이를 해석하지 않습니다.

프로그램 이름과 인수 (일명 간단한 명령)을 저장하는 올바른 방법은 배열을 사용하고 있습니다 :

cmd=(ls 'my dir') 
result=$("${cmd[@]}") 

배쉬 것입니다 이유를 예를 때로는 당신이하지 않는 큰 따옴표, 공간에 자동으로 분할 단어 작동하는 것처럼 보입니다. 이것은 놀랍고 오류가 발생하기 쉽기 때문에, 당신이 좋은 이유가 없다면 변수를 항상 두 번 인용해야하는 이유입니다.

문자열을 완벽하게 마치 bash 코드로 해석하도록 bash에 넣을 수도 있습니다 (eval 사용). 이것은 자주 권장되지만 거의 항상 잘못된 것입니다.

-1

용액 1 : sh -c

mkdir 'my dir' 
CMD="ls 'my dir'" # careful: your example was missing a ' 
RESULT=$(sh -c "$CMD") 

해결책 2 : 배열로 CMD 선언

mkdir 'my dir' 
CMD=(ls 'my dir') # array with 2 elements 
RESULT=$("${CMD[@]}") 
+2

-1 : "솔루션 1"은 부모 프로세스에서 변수를 변경할 수 없으며 하위 프로세스 실행의 오버 헤드를 모두 갖고 bash에서 bash로 전환하는 것을 제외하고는 'eval'을 사용하는 것과 도덕적으로 동일합니다. 해당 부속 명령의 지속 기간 동안 국지적으로 설치된 POSIX sh 해석기. –