bash 변수 확장이 따옴표를 유지하는 이유는 무엇입니까?


12
> echo "hi"
hi
> VAR='echo "hi"'
> $VAR
"hi"

위 명령의 출력이 다른 이유는 무엇입니까?

작은 따옴표로도 비슷한 일이 발생합니다.

> VAR="echo 'hi'"
> $VAR
> 'hi'

6
실행 가능한 스크립트 스 니펫을 변수에 임베드하지 마십시오. 이 경향 최선을 교묘 하고 eval당신은 매우 신중해야한다 잠재적 인 보안 구멍의 지뢰밭이다
jw013

@ jw013 좋은 지적과 훌륭한 기사. "변수는 데이터를 보유하고, 함수는 코드를 보유합니다." 첫 번째 링크에서, 그러나 내 사용을 위해 함수 (이 경우 at) 에 제공된 데이터 코드입니다. 코드를 안전하게 구성 / 수집하는 방법에 대한 팁이 at있습니까?
코리 클라인

at필요 sh입력으로 구. 따라서 입력을 at생성한다는 sh것은 임의의 입력에서 유효하고 올바르게 인용 된 구문을 생성 하는 것을 의미 합니다. 달성하려는 것에 대해 좀 더 자세하게 설명 할 수 있다면 정말 도움이 될 것입니다.
jw013

죄송합니다. 너무 자세하게 산만하고 싶지는 않지만 제가하고있는 일은 실제로 복잡한 것은 아닙니다. IMO. "시간"과 "메시지"가 필요한 스크립트를 작성 중입니다. 그런 다음 at주어진 "시간"동안 at실행되고 명령을 실행하도록 지시 합니다 dzen2. dzen2stdin에서 "메시지"를 가져오고 다른 정적 매개 변수도 사용합니다. 어려움은 내가 파이프로에 사용자로부터 "메시지"매개 변수를 필요로한다는 것입니다 dzen2명령을하지만 실제로 운영하지 않는 dzen2내가 말하고, 자신이 at그것을 할 수 있습니다.
코리 클라인

답변:


16

여분의 따옴표 쌍은 추가 평가 단계에 의해서만 소비됩니다. 예를 들어 강제 eval:

bash-4.2$ VAR='echo "hi"'

bash-4.2$ $VAR
"hi"

bash-4.2$ eval $VAR
hi

그러나 일반적으로 매개 변수가있는 명령을 하나의 문자열에 넣는 것은 좋지 않습니다. 대신 배열을 사용하십시오.

bash-4.2$ VAR=(echo "hi")

bash-4.2$ "${VAR[@]}"
hi

1
따옴표는 다르게 평가된다는 점에 유의해야합니다. . 큰 따옴표 ( ") 동봉 된 문자열의 평가는, 단일 따옴표 ( ') 리터럴로 문자열을 인쇄 할 수 있습니다 예 : "$(ls)"'$(ls)'따옴표는 원래 질문의 예에 나타나는 이유는 이유입니다..
조셉 컨에게

배열도 문제의 원인입니다. 코드는 함수, 데이터는 변수에 속합니다. 제시 한 예제는 따옴표가 배열의 분할에서 제거되기 때문에 작동합니다. A printf '<%s> ' "${VAR[@]}"는 따옴표가 이미 제거되었음을 나타냅니다. 당신이 VAR를 설정하면 VAR=(echo \"hi\")실제로 따옴표를 가지고, 같은 문제가 다시 나타나면, $ ${VAR[@]}인쇄됩니다"hi"

9

따옴표 제거 는 확장 결과가 아닌 원래 입력 단어에서만 발생합니다 . 확장 변수의 일부인 따옴표는 그대로 유지됩니다.


2

조금 뒤로 물러 서면 변수 대체가 절대적으로 따옴표를 유지 해야하는 이유를 알 수 있습니다.

유닉스 / 리눅스 / BSD 쉘에서 인용 포인트는 여러 개의 문자열로 해석되는 문자열 조각을 함께 유지하는 것입니다. 쉘은 기본적으로 공백을 토큰 분리 자로 사용하기 때문에 공백이있는 문자열 (예 : "1 2 3")은 인용되거나 이스케이프되지 않으면 "1", "2"및 "3"이라는 3 개의 문자열로 구문 분석됩니다.

프로그래머가 보간 된 일부 변수 값을 가진 문자열을 원할 경우 :

VAR=two
STRING="one $VAR three"

쉘은 따옴표를 절대로 제거해서는 안됩니다. 공백이 포함 된 문자열은 3 개의 작은 문자열로 구문 분석됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.