Ответы:
`date` просто расширится до вывода date
команды. Однако он удаляет лишние пробелы в тех местах, где в выводе содержится более одного последовательного пробела. (Это связано с тем, что подстановка команд подвержена разбиению слов и из-за того, как echo
команда обрабатывает несколько аргументов.)
В «date» двойные кавычки являются слабыми, поэтому они будут раскрывать переменные (попробуйте «$ PWD») и выполнять подстановку команд. Результат раскрытия передается команде как один аргумент echo
с включенными последовательными пробелами: то есть разделение слов не выполняется.
В `` date` ' одинарные кавычки являются более сильными кавычками, поэтому они не допускают расширения переменных или подстановки команд внутри них.
Перейдите по этой ссылке для получения дополнительной информации.
Отредактировал первый пункт, как правильно указал Михаэль Зельманн в комментарии ниже .
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
были сокращены до одного без кавычек. Это связано с тем, что оболочка анализирует каждый разделенный пробелами элемент и отправляет результат в echo в качестве 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`, поскольку между одинарными кавычками нет подстановки команд.
Возможно, различия в 3 формах будут более заметны таким образом:
> 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`