Відповіді:
`date` просто розшириться до виводу date
команди. Однак він видаляє зайвий пробіл символів у місцях, де у виході є більше одного послідовного символу пробілу. (Це відбувається тому, що заміна команди підлягає розбиткові слів і тому, як echo
команда обробляє декілька аргументів.)
У "date" " подвійні лапки - це слабкі лапки, тому вони розширять змінні (спробуйте" $ PWD ") та виконають підстановку команд. Результат розширення передається команді як єдиний аргумент echo
з будь-якими послідовними пробілами: тобто розщеплення слів не виконується.
У "дати" одиничні лапки є сильнішими цитатами, тому вони не дозволять розширювати змінні чи замінювати команди всередині них.
Перейдіть за цим посиланням для отримання додаткових пояснень.
Перший пункт редагував так, як правильно вказав Майкл Суельман у коментарі нижче .
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 аргументів. Коли ви цитуєте його, ехо отримує один єдиний аргумент, і лапки залишають простір.
Це стає набагато важливішим у інших командах, ніж відлуння. Наприклад, уявіть команду, 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
щоб вимкнути його.Одиночні цитати цитують все, що спричиняє сприйняття символів "backtick" буквально.
Приклад (з використанням -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`