답변:
`date` 는 date
명령 의 출력으로 확장됩니다 . 그러나 출력에 연속 공백 문자가 두 개 이상있는 위치에서 여분의 공백 문자가 제거됩니다. (이는 명령 대체가 단어 분할에 종속되고 echo
명령이 여러 인수를 처리 하는 방식 때문입니다 .)
에서 "`date`" 그들이 변수를 확장 ( "$ PWD"를 시도) 및 명령 대체를 수행 할 수 있도록, 따옴표는 약한 따옴표입니다. 확장 결과는 연속 된 공백을 포함 하여 명령에 단일 인수로 전달됩니다 echo
. 즉, 단어 분할이 수행 되지 않습니다 .
에서 '`date`' 그들이 내에서 변수 나 명령 치환의 확장을 허용하지 않도록, 작은 따옴표는, 강한 따옴표입니다.
자세한 설명은 이 링크 를 참조하십시오 .
아래 주석 에서 Michael Suelmann이 올바르게 지적한대로 첫 번째 점을 편집했습니다 .
date
명령 과 동일한 내용을 출력합니다 .
양자 모두
echo `date`
과
echo "`date`"
날짜가 표시됩니다. 후자의 출력은 date
자체 실행의 출력과 같습니다 .
그러나 차이 가 있습니다. "
따옴표로 묶은 것은 단일 인수로 "
전송됩니다 echo
. 따옴표는 전체 명령의 출력을 하나의 인수로 캡슐화합니다. 그 echo
사이에 공백이있는 순서대로 인수를 인쇄하기 때문에 기본적으로 동일하게 보입니다.
미묘한 차이의 예는 다음과 같습니다.
echo `date`
생산 :
Fri Nov 1 01:48:45 EST 2013
그러나:
echo "`date`"
생산 :
Fri Nov 1 01:48:49 EST 2013
이후의 두 공백 Nov
은 따옴표없이 하나로 줄어 듭니다. 쉘이 공백으로 구분 된 각 요소를 구문 분석하고 결과를 6 개의 인수로 에코에 보내기 때문입니다. 인용하면 echo는 하나의 인수를 받고 인용 부호는 공백을 유지합니다.
이것은 echo 이외의 명령에서 훨씬 더 중요해집니다. 예를 들어, foo
날짜와 이메일 주소라는 두 가지 인수를 원하는 명령 을 상상해보십시오 .
이것은 해당 시나리오에서 작동합니다.
foo "`date`" joeuser@example.com
그러나 이것은 7 개의 인수를 보내서 스크립트를 혼란스럽게합니다.
foo `date` joeuser@example.com
POSIX 쉘 `date`
에서 고대 형태의 명령 대체입니다. 현대 구문은 $(date)
입니다.
두 경우 모두 date
후행 줄 바꿈 문자를 제거 하여 출력으로 확장합니다 (출력에 NUL 문자가 포함되어 있지 않은 경우).
그러나 큰 따옴표 안에 있지 않고 목록 컨텍스트에없는 경우 (예를 들어 echo
귀하의 경우 와 같은 간단한 명령에 대한 인수 ) 해당 확장에는 다음이 추가로 적용됩니다.
단어 분리 : 즉, " date
마지막 줄 바꿈 문자가 제거 된 결과" 는 $IFS
변수 의 현재 값 (기본적으로 공백, 탭 및 줄 바꿈 (및 NUL 포함 zsh
))에 따라 여러 단어 로 분할됩니다 .
예를 들어, 영어 로케일과 영국 본토 시간대에서 자주 date
출력되는 Fri 1 Nov 14:11:15 GMT 2013\n
것과 같이 출력이 $IFS
현재 포함되어있는 :
경우 3 단어 : Fri 1 Nov 14
, 11
및 로 나뉩니다 15 GMT 2013
.
zsh
) : (즉, 위의 분할로 인한 각 단어는 와일드 카드 문자를보고있다 *
, ?
, [...]
약간의 껍질을 더 가지고 있지만), 그 패턴과 일치하는 파일 이름 목록에 확장했다. 예를 들어,의 출력이있는 경우 date
입니다 ?%? 33 */*/* UVC 3432
(종종 금성 로케일과 UVC 시간대에 같은), 그리고 $IFS
) 기본값입니다, 그 모든 팽창 비 숨겨진 그 중간 문자 현재 디렉토리에 3 문자 파일 이름 %
, 33
, 모든 숨겨지지 않은 현재 디렉토리의 하위 디렉토리의 모든 숨겨지지 않은 하위 디렉토리에있는 모든 비 숨김 파일 UVC
및 3432
.그 이유는 다음과 같습니다.
$IFS
당신이 분할하려는 자.set +f
작은 따옴표는 모든 것을 인용하므로 백틱 문자가 문자 그대로 사용됩니다.
예를 사용 -x
하면 진행 상황을 쉽게 볼 수 있습니다.
$ bash --norc -x
bash-4.2$ IFS=:
+ IFS=:
bash-4.2$ echo `date`
++ date
+ echo 'Fri 1 Nov 14' 42 '33 GMT 2013'
Fri 1 Nov 14 42 33 GMT 2013
bash-4.2$ echo "`date`"
++ date
+ echo 'Fri 1 Nov 14:42:41 GMT 2013'
Fri 1 Nov 14:42:41 GMT 2013
bash-4.2$ cd /lib/modules
+ cd /lib/modules
bash-4.2$ export TZ=UVC LC_ALL=vs_VS
+ export TZ=UVC LC_ALL=vs_VS
+ TZ=UVC
+ LC_ALL=vs_VS
bash-4.2$ unset -v IFS # get the default behaviour
+ unset -v IFS
bash-4.2$ echo `date`
++ date
+ echo '?%?' 33 3.10-2-amd64/build/arch 3.10-2-amd64/build/include 3.10-2-amd64/build/Makefile 3.10-2-amd64/build/Module.symvers 3.10-2-amd64/build/scripts 3.10-2-amd64/kernel/arch 3.10-2-amd64/kernel/crypto 3.10-2-amd64/kernel/drivers 3.10-2-amd64/kernel/fs 3.10-2-amd64/kernel/lib 3.10-2-amd64/kernel/mm 3.10-2-amd64/kernel/net 3.10-2-amd64/kernel/sound 3.10-2-amd64/source/arch 3.10-2-amd64/source/include 3.10-2-amd64/source/Makefile 3.10-2-amd64/source/scripts 3.10-2-amd64/updates/dkms 3.10-3-amd64/build/arch 3.10-3-amd64/build/include 3.10-3-amd64/build/Makefile 3.10-3-amd64/build/Module.symvers 3.10-3-amd64/build/scripts 3.10-3-amd64/kernel/arch 3.10-3-amd64/kernel/crypto 3.10-3-amd64/kernel/drivers 3.10-3-amd64/kernel/fs 3.10-3-amd64/kernel/lib 3.10-3-amd64/kernel/mm 3.10-3-amd64/kernel/net 3.10-3-amd64/kernel/sound 3.10-3-amd64/source/arch 3.10-3-amd64/source/include 3.10-3-amd64/source/Makefile 3.10-3-amd64/source/scripts 3.10-3-amd64/updates/dkms UVC 3432
?%? 33 3.10-2-amd64/build/arch 3.10-2-amd64/build/include 3.10-2-amd64/build/Makefile 3.10-2-amd64/build/Module.symvers 3.10-2-amd64/build/scripts 3.10-2-amd64/kernel/arch 3.10-2-amd64/kernel/crypto 3.10-2-amd64/kernel/drivers 3.10-2-amd64/kernel/fs 3.10-2-amd64/kernel/lib 3.10-2-amd64/kernel/mm 3.10-2-amd64/kernel/net 3.10-2-amd64/kernel/sound 3.10-2-amd64/source/arch 3.10-2-amd64/source/include 3.10-2-amd64/source/Makefile 3.10-2-amd64/source/scripts 3.10-2-amd64/updates/dkms 3.10-3-amd64/build/arch 3.10-3-amd64/build/include 3.10-3-amd64/build/Makefile 3.10-3-amd64/build/Module.symvers 3.10-3-amd64/build/scripts 3.10-3-amd64/kernel/arch 3.10-3-amd64/kernel/crypto 3.10-3-amd64/kernel/drivers 3.10-3-amd64/kernel/fs 3.10-3-amd64/kernel/lib 3.10-3-amd64/kernel/mm 3.10-3-amd64/kernel/net 3.10-3-amd64/kernel/sound 3.10-3-amd64/source/arch 3.10-3-amd64/source/include 3.10-3-amd64/source/Makefile 3.10-3-amd64/source/scripts 3.10-3-amd64/updates/dkms UVC 3432
bash-4.2$ echo "`date`"
++ date
+ echo '?%? 33 */*/* UVC 3432'
?%? 33 */*/* UVC 3432
출력에 NUL 문자가 포함 된 경우 동작은 쉘마다 다릅니다. 일부는 제거하고 일부는 첫 번째 NUL 문자에서 출력을 자르고 zsh
유지하지만 외부 명령은 NUL을 포함하는 인수를 사용할 수 없습니다.
`date`를 사용하면 명령 대체 후에 단어 분할이 수행되므로 날짜 출력이 여러 단어로 분할됩니다.
"`date`"를 사용하면 큰 따옴표 사이에 명령 대체가 있기 때문에 날짜 출력을 하나의 단어 / 매개 변수로 얻을 수 있지만 출력은 더 이상 구문 분석되지 않습니다. 아래 예에서 "$ i"와 같은 변수 확장에서도 마찬가지입니다.
'`date'를 사용하면 작은 따옴표 사이에 명령 대체가 없으므로 리터럴`date`가 표시됩니다.
아마도 세 가지 형식의 차이점이 다음과 같이 더 잘 보일 것입니다.
> for i in `date`; do echo "$i"; done
Fr
1.
Nov
12:25:30
CET
2013
> for i in "`date`"; do echo "$i"; done
Fr 1. Nov 12:25:38 CET 2013
> for i in '`date`'; do echo "$i"; done
`date`