따옴표 붙은 따옴표없는 문자열 확장


11
  1. for i in $(xrandr); do echo "$i" ; done
  2. for i in "$(xrandr)"; do echo "$i"; done
  3. for i in "$(xrandr)"; do echo $i; done

1이 2와 다른 이유를 이해하지만 3이 2와 다른 결과를주는 이유는 무엇입니까? 출력도 설명 해주세요. 따옴표는 줄 바꿈에서 어떻게 작동합니까?



답변:


19

인용되지 않은 (같이 가변 $var) 또는 (같이 명령 치환 $(cmd)또는 `cmd`)는 IS 분할 + 글로브의 연산자 본쉘.

즉, 내용은 $IFS특수 변수 의 현재 값에 따라 분할됩니다 (기본적으로 공백, 탭 및 줄 바꿈 문자가 포함됨)

그런 다음 해당 분할로 인한 각 단어는 파일 이름 생성 (글 로빙 또는 파일 이름 확장 이라고도 함 )의 대상 이됩니다. 즉, 패턴으로 간주되어 해당 패턴과 일치하는 파일 목록으로 확장됩니다.

그래서에서 for i in $(xrandr)$(xrandr)이 따옴표 아니기 때문에, 공백, 탭과 개행 문자의 순서에 분할이다. 그리고 그 분리로 인한 각 단어는 일치하는 파일 이름이 있는지 확인하거나 파일과 일치하지 않는 경우 그대로 for둡니다.

에서 for i in "$(xrandr)", 우리는 명령 대체 가 인용 될 때 split + glob 연산자를 사용하지 않기 때문에, 하나의 값 에 대한 루프에는 하나의 패스가 있습니다 : xrandr( 명령 대체가 제거 하는 후행 줄 바꿈 문자없이) 출력 .

그러나에 echo $i, $i그렇게 다시 콘텐츠를 다시 인용되지 않은되어 $i분할 및 대상이다 파일명 생성 하고 그는 별도의 인수로 전달되는 echo명령 (및 echo출력 인자가 공백으로 분리).

그래서 교훈은 배웠습니다.

  • 단어 분할 또는 파일 이름 생성을 원하지 않는 경우 항상 변수 확장 및 명령 대체를 인용하십시오.
  • 단어 분할 또는 파일 이름 생성을 원할 경우 인용되지 않은 채로 그대로두고 $IFS필요에 따라 파일 이름 생성을 활성화 또는 비활성화하십시오 ( set -f, set +f).

일반적으로 위의 예에서의 출력에서 ​​공백으로 구분 된 단어 목록을 반복 xrandr하려면 다음을 수행해야합니다.

  • $IFS공백으로 분할하려면 기본값을 그대로 두거나 설정을 해제하십시오.
  • 사용 set -f안 함 파일 이름 생성을하지 않는 한 당신이 확신하는 것이 xrandr어떤 출력 적이 *거나 ?또는 [(와일드 카드 파일 이름 생성 패턴에 사용되는) 문자

그런 다음 루프 in부분 에서 split + glob 연산자 만 사용하십시오 (명령 대체 또는 변수 확장 만 인용되지 않은 상태로 두십시오) for.

set -f; unset -v IFS
for i in $(xrandr); do whatever with "$i"; done

출력 의 비어 있지 않은 을 반복 하려면 줄 바꿈 문자 xrandr로 설정 $IFS해야합니다.

IFS='
'

4

인용 된 줄 바꿈은 줄 바꿈입니다. 따라서 echo "$1"echo에 단일 명령 행 인수를 제공하여 줄 바꾸기를 직접 인쇄합니다.

따옴표없는 줄 바꿈은 공백입니다. 따라서 echo $1에코에 많은 명령 행 인수를 제공하여 공백으로 구분하여 차례로 인쇄합니다.


인용되지 않은 줄 바꿈은 공백 이 IMO의 동작에 대한 설명으로 실제로 유용하기에는 너무 짧습니다.
Stéphane Chazelas 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.