명령 대체 시 Bash 인용문이 이스케이프되지 않음

명령 대체 시 Bash 인용문이 이스케이프되지 않음

누군가 이것이 작동하는 이유를 설명할 수 있습니까(이름에 공백이 있는 디렉토리의 내용 나열):

ret="$(ls "my dir")"

오히려 다음과 같이 해석되어야 하지 않을까요?

ret="$(ls "
my dir
")"

예를 들면 다음과 같습니다.

ls "my" "dir"

그리고

ls "my dir"

답변1

지금까지 가장 좋은 추측은 다음과 같이 묻는 것 같습니다.

명령

    ret="$(ls "내 디렉토리")"

는 네 개의 큰따옴표( ") 표시가 포함된 명령의 매우 끔찍한 예입니다. 다음과 같이 두 번째 인용문이 첫 번째 인용문과 일치하고 네 번째 인용문이 세 번째 인용문과 일치할 것이라고 순진하게 기대할 수도 있습니다.

    ret="$(ls "my dir")"
        ↑-----↑      ↑-↑

예를 들어

    eat "afternoon snack" dinner "midnight snack"

대신 다음과 같이 "작동"합니다.

    ret="$(ls "내 디렉토리")"
        ↑ ↑------↑ ↑
        ↑---------------↑

중첩된 따옴표가 왜 그런 식으로 구문 분석되나요?

이 단락의배쉬(1) 그것을 설명할 수 있습니다:

명령 대체

                        ⋮
    ... 형식을 사용할 때 괄호 안의 모든 문자가 명령을 구성합니다 ....$(command)

$(나는 이것이 당신이 관찰한 것을 의미한다고 생각합니다. 즉, the 와 the 사이의 텍스트는 )괄호 밖의 구문 요소와 관계없이 자체 구문 분석/따옴표 쌍을 사용하여 별도의 명령인 것처럼 처리됩니다. 그 의미를 찾고 있지 않다면 해석하기가 매우 어렵다는 점은 인정합니다.


그러나 귀하의 질문은 서면으로 이해되지 않습니다. 모든 것은 $껍질 의 매우 특별한 의미에 달려 있습니다 . 이를 다른 통화 기호로 변경하면

    ret="£(ls "my dir")"

그러면 두 단어로 처리됩니다.

        ret="£(ls "my
(뒤에)
                                    dir")"

공백이 아니고 특수 문자가 아닌 문자가 여는 따옴표 바로 앞이나 닫는 따옴표 바로 뒤에 나타나면 따옴표로 묶인 문자와 동일한 문자열에 포함되기 때문입니다. 예를 들어,

    cat Wal"*"mart

Wal*mart이라는 파일이 아닌 이라는 파일을 찾습니다 Wal. 하나는 이고 *하나는 이라고 합니다 mart. 이는 및 Wal"*"mart와 동일합니다 . 마찬가지로 다음 예에서는 4개의 단어를 보여줍니다.Wal\*mart"Wal*mart"

    하나" "두 버클" 내 "신발 /don\'t/be/a/" "/cadet sqrt"(2)"
    ↑---------↑ ↑---------------↑ ↑---------↑ ↑-- -----↑

귀하의 질문에 표시된 세 줄의 분석을 어디서 얻었는지 모르겠습니다.

관련 정보