Каково различие между эхом 'дата', эхо “'дата'”, и эхом ''дата''?

необходимо использовать:

top -n 1 | grep "blah" > top.log

вершина выполнений "-n 1" для одного повторения и затем выходит вместо того, чтобы постоянно обновить каждые несколько секунд

так как Вы просто ищете одну строку, хотя PS был бы лучшим инструментом для использования.

23
02.11.2013, 01:41
4 ответа

'дата' просто расширится до вывода date команда. Однако это удаляет символы дополнительного пространства в местах, где существует больше чем один последовательный пробел в выводе. (Это вызвано тем, что замена команды подвергается разделению слова, и из-за как echo управляйте обрабатывает несколько аргументов.)

На "'дате'" двойные кавычки являются слабыми кавычками, таким образом, они расширятся, переменные (попробуйте "$PWD"), и выполните замену команды. Результат расширения передается как отдельный аргумент echo команда, с любыми последовательными включенными пробелами: то есть, разделение слова не выполняется.

На ''дате'' одинарные кавычки являются более сильными кавычками, таким образом, они не будут позволять расширение переменных или управлять заменой в них.

Отошлите эту ссылку для большего количества объяснения.

Отредактированный первая точка, как правильно указано Michael Suelmann в комментарии ниже.

19
27.01.2020, 19:41
  • 1
    Каков точно 'символ, который окружает названную дату? Если я пойму правильно, то метасимволы не будут работать в единственных цитатах? –  John 01.11.2013, 08:27
  • 2
    Если я пойму правильно, то метасимволы не будут работать в единственных цитатах? –  John 01.11.2013, 08:46
  • 3
    ' Часто называется "обратной галочкой" в том сценарии и различной документации/книгах Unix. Это на самом деле не используется в качестве диакритического знака могилы Unicode, когда это самостоятельно похоже на это, даже при том, что это - название символа. И Вы корректны, что никакое расширение метасимволов/выражений не произойдет при окружении его одинарными кавычками. –  Jim Stewart 01.11.2013, 08:55
  • 4
    Ваш первый оператор является неправильным, поскольку вывод мог бы немного отличаться в зависимости от даты или локали. Только вторая команда произведет то же самое как пустое date команда. –  jlliagre 01.11.2013, 10:08
  • 5
    @BonsiScott, дополнительное пространство между "ноябрем" и "1" удалено в HTML также ;) –  Izkata 01.11.2013, 17:53

Оба

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
16
27.01.2020, 19:41
  • 1
    Вы сам противоречащий в Вашем первом предложении. Первая и вторая форма будет не всегда производить то же самое, как Вы демонстрируете позже. –  jlliagre 01.11.2013, 10:10
  • 2
    Спасибо. Я изменил формулировку для создания этого более ясным. –  Jim Stewart 01.11.2013, 18:13

В оболочках POSIX, `date` древняя форма замены команды. Современный синтаксис $(date).

В обоих случаях они расширяются до вывода date с запаздывающими разделенными символами новой строки (при условии, что произведенный не содержит символы NUL).

Однако если не в двойных кавычках и в контекстах списка (например, в аргументах простым командам как echo в Вашем случае), то расширение является дальнейшим предметом к:

  1. Разделение Word: это - "вывод date с запаздывающими символами новой строки, разделенными", разделяется согласно текущему значению $IFS переменная (значением по умолчанию, содержащим пространство, вкладку и новую строку (и NUL с zsh)) в несколько слов.

    Например, если date выводы Fri 1 Nov 14:11:15 GMT 2013\n (как он часто делает в английской локали и в материковом британском часовом поясе), и $IFS в настоящее время содержит :, это будет разделено на 3 слова: Fri 1 Nov 14, 11 и 15 GMT 2013.

  2. Поколение имени файла (иначе globbing) (кроме с zsh): то есть, каждое слово, следующее из разделения выше, ищется подстановочные символы (*, ?, [...] хотя некоторые оболочки имеют больше), и расширенный до списка имен файлов, которые соответствуют тем шаблонам. Например, если вывод date ?%? 33 */*/* UVC 3432 (как он часто находится в локалях Венерианца и часовом поясе UVC), и $IFS значение по умолчанию), затем это расширяется до всех нескрытых 3 символьных имен файлов в текущем каталоге, средний символ которого %, 33, все нескрытые файлы во всех нескрытых подкаталогах всех нескрытых подкаталогов текущего каталога, UVC и 3432.

Именно поэтому:

  1. Необходимо всегда заключать в кавычки (с двойными кавычками) замены команды, если Вы действительно не хотите или разделение слова или поколение имени файла, выполненное после его расширения
  2. Если Вы действительно хотите разделение слова, то необходимо установить $IFS к символам Вы хотите разделить на.
  3. Если Вы хотите разделение слова, но не поколение имени файла, Вам нужно к проблеме a 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 сохраняет их, но обратите внимание, что так или иначе внешние команды не могут взять аргументы, содержащие NULs

3
27.01.2020, 19:41
  • 1
    Нет такой вещи как фактическая "оболочка POSIX". Существуют оболочки, которые могут соответствовать различным соответствующим стандартам POSIX при помощи ограниченного подмножества их функциональности. –  fpmurphy 01.12.2017, 03:31

С 'датой' Вы получаете вывод даты, разделенной на несколько слов, потому что разделение слова сделано после замены команды.

С "'датой'" Вы получаете вывод даты как одно слово/параметр, поскольку существует замена команды между двойными кавычками, но вывод не анализируется далее. То же допустимо с переменным расширением как "$i" в моем примере ниже.

С ''датой'' Вы получаете литеральную 'дату', поскольку нет никакой замены команды между одинарными кавычками.

Возможно, различия 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`
0
27.01.2020, 19:41

Теги

Похожие вопросы