A=\"\" grep $A 가 grep "" 처럼 동작하지 않는 이유는 무엇입니까?

A=\"\" grep $A 가 grep "" 처럼 동작하지 않는 이유는 무엇입니까?

저는 Linux에서 bash를 사용하고 있습니다.

$ A=\"\"
$ grep $A
nomatch
""
""                         <- (returned by grep)
$ grep ""
imatcheverything
imatcheverything           <- (returned by grep)

grep $A나는 그런 식으로 행동할 것으로 예상됐다 grep "". 문자 그대로 일치하는 이유는 무엇입니까 ""? grep예를 들어 (내가 알 수 있는 한) 쉘 grep \\\\은 먼저 쉘에서 살펴본 다음 grep \\. 라인이 포함되어 있습니다 \.

나는 이것이 쉘이 변수를 대체하고 따옴표를 보는 순서와 관련이 있다고 생각합니다. 이 동작은 변수 대체 단계 전에 쉘이 따옴표를 제거한 경우 설명될 수 있습니다.


관련 없는 메모에서 저는 상대적으로 복잡한 정규 표현식(쓰기가 아닌 읽기, 이상적으로는 "이 정규 표현식의 기능은 무엇입니까?"라고 묻는 것)이 있는 리소스를 찾고 있으며 BRE 또는 ERE가 바람직합니다.

답변1

Bash는 인수 확장 후 따옴표를 평가하지 않습니다. 확장된 값만 처리분사그리고파일 이름 확장자변수를 따옴표로 묶지 않으면 따옴표가 더 이상 재해석되지 않습니다. IFS 및 glob이 아닌 다른 값과 마찬가지로 "단어"의 일부가 됩니다. 귀하의 예에서 Bash는 ""단어 분할이나 glob 패턴이 아니기 때문에 인수를 grep에 그대로 전달합니다 .

답변2

$ A = \"\"
$ grep $A

Bash에서는 등호 주위에 공백이 없고 그 앞에도 공백이 없으며 뒤에도 공백이 없습니다.

$ A=\"\"
$ grep $A

답변3

grep ""빈 문자열 인수를 사용하여 grep을 호출합니다.

grep $A(즉 grep \"\", 실제로 두 개의 큰따옴표인 하나의 인수로 grep을 호출합니다.

쉘이 명령으로 보내는 내용을 알고 싶다면 아래와 같이 작은 스크립트를 사용하여 알아낼 수 있습니다.

#!/usr/bin/python3

import sys

args = sys.argv[1:] #skip the first one which is the name of the cmd

print(f"Number of args: {len(args)}")

for index, arg in enumerate(args, start=1):
    print(f"Arg {index}: Length: {len(arg)}")
    for char in arg:
        print(f"{ord(char)} {char}")

예시 1:

❯ ./showargs.py ""
Number of args: 1
Arg 1: Length: 0

예 2:

❯ A=\"\"
❯ ./showargs.py $A  
Number of args: 1
Arg 1: Length: 2
34 "
34 "

예시 3:

❯ ./showargs.py foo \\\\
Number of args: 2
Arg 1: Length: 3
102 f
111 o
111 o
Arg 2: Length: 2
92 \
92 \

관련 정보