Echo `date`, echo“ `date`” ve echo '`date`' arasındaki fark nedir?


23

Bu üç komut arasındaki fark nedir?

echo `date`
echo "`date`"
echo '`date`'

Farklılıkların gerçekte ne olduğu konusunda kafam karıştı. Ben 'etrafında olduğunda bir dize olduğu anlamına gelir, bu nedenle eko tam anlamıyla datetarihi görüntülemek yerine dize çıktı ?

Yanıtlar:


19

`date` sadece datekomutun çıktısına genişler . Bununla birlikte, çıktıda birden fazla ardışık boşluk karakteri bulunan yerlerde fazladan boşluk karakterleri kaldırır. (Bunun nedeni, komut değiştirme işleminin kelime bölmeye tabi olması ve echokomutun çoklu argümanları nasıl ele alması nedeniyle olmasıdır .)

In "` date`" onlar değişkenleri genişletmek ( "$ PWD" deneyin) ve komut ikamesi yapacak bu nedenle, çift tırnak, zayıf tırnaklar vardır. Genleşme sonucu olarak geçirilen bir argüman echodahil herhangi bir ardışık alanlar ile, komut: olup, kelime bölme edilir değildir gerçekleştirilir.

In '`date`' onlar içlerinde değişkenleri veya komut ikamesi genişlemesine izin vermez, böylece tek tırnak, güçlü alıntılar var.

Daha fazla açıklama için bu bağlantıya bakın .

İlk yorumu , Michael Suelmann'ın aşağıdaki açıklamada gösterildiği gibi doğru bir şekilde düzenledi .


1
Tam olarak çevresindeki tarihi olan `karakteri nedir? Doğru anlıyorsam meta karakterler tek alıntılarda çalışmayacak mı?
John

Doğru anlıyorsam meta karakterler tek alıntılarda çalışmayacak mı?
John

8
`Bu senaryoda ve çeşitli Unix belgelerinde / kitaplarında genellikle" ters vuruş "denir. Aslında sembolün adı olmasına rağmen, tek başına olduğu zaman Unicode mezar aksanı olarak kullanılmıyor. Ayrıca, tek tırnaklarla çevrelerseniz meta karakterlerin / ifadelerin genişlemesinin gerçekleşmeyeceği konusunda haklısınız.
Jim Stewart

İlk deyiminiz çıktı tarih veya yerel ayarlara bağlı olarak biraz farklı olabileceğinden yanlıştır. Yalnızca ikinci komut, çıplak datekomutla aynı şeyi verir .
jlliagre

1
@BonsiScott "Nov" ve "1" arasındaki fazladan boşluk HTML'de de kaldırılır;)
Izkata

16

Her ikisi de

echo `date`

ve

echo "`date`"

tarihi gösterecektir. İkincisinin çıktısı, çıkışın datekendiliğinden çalışmasına benziyor .

Yine de, bir fark var: "alıntılarla çevrili olan tek bir argüman olarak "gönderilecek echo. Tırnaklar, tüm komutun çıktısını tek bir argüman olarak içerir. Yana echosadece aradaki boşluklarla, sırayla kendi argümanları yazdırır, temelde aynı görünür.

İşte ince farkın bir örneği:

echo `date`

üretir:

Fri Nov 1 01:48:45 EST 2013

fakat:

echo "`date`"

üretir:

Fri Nov  1 01:48:49 EST 2013

Sonrasında iki boşluğun Novtırnak işaretleri olmadan bir kısaltılmış olduğuna dikkat edin. Bunun nedeni, kabuğun boşlukla ayrılmış her öğeyi ayrıştırması ve sonucu 6 bağımsız değişken olarak yankıya göndermesidir. Alıntı yaptığınızda, yankı tek bir argüman alır ve tırnaklar alanı korur.

Bu, yankı dışındaki komutlarda çok daha önemli hale gelir. Örneğin, fooiki argüman isteyen bir komut düşünün : bir tarih ve bir e-posta adresi.

Bu, bu senaryoda işe yarayacaktır:

foo "`date`" joeuser@example.com

Fakat bu senaryoyu 7 argüman göndererek karıştırır:

foo `date` joeuser@example.com

3
İlk cümlenizde kendinizle çelişiyorsunuz. Birinci ve ikinci form daima daha sonra gösterdiğinizle aynı şeyi vermeyecektir.
jlliagre

Teşekkürler. Daha net hale getirmek için ifadeleri değiştirdim.
Jim Stewart,

3

POSIX mermilerinde, `date`eski komut ikame şeklidir. Modern sözdizimi $(date).

Her iki durumda da date(çıkışın NUL karakterleri içermemesi koşuluyla) izlenen son satırdaki yeni karakterlerin çıktısına kadar genişler .

Bununla birlikte, çift tırnak içinde ve liste içeriğinde olmadığında (örneğin; echo , sizin durumunuzdaki ) olmadığı zaman, bu genişleme aşağıdakilere de tabidir:

  1. Kelime bölme : " dateizlenen satır sonundaki yeni satır karakterlerinin çıktısı " , $IFSdeğişkenin geçerli değerine göre (varsayılan olarak boşluk, sekme ve yeni satır (ve NUL zsh)) bölünerek kelimeye .

    Örneğin, eğer dateçıkışları Fri 1 Nov 14:11:15 GMT 2013\n(genellikle bir İngiliz yerel ayarda ve bir anakara İngiliz saat diliminde yaptığı gibi) ve $IFSşu anda içeren :, yani 3 içine bölünmüş olacaktır deyişle : Fri 1 Nov 14,11 ve 15 GMT 2013.

  2. Dosya adı nesil (aka globbing (hariç) zsh): (olduğunu, yukarıdaki bölme kaynaklanan her kelime joker karakterler için aranır *, ?, [...]bazı kabukları fazlasına sahip olsa da) ve bu kalıplarla eşleşen dosya adları listesine genişletti. Örneğin, çıkış ise dateise ?%? 33 */*/* UVC 3432(genellikle Venüs yerel ve UVC saat diliminde olduğu gibi) ve $IFS) varsayılan değerdir, o herkese genişlediğinde olmayan gizli olan orta karakterdir geçerli dizinde 3 karakter dosya adları %, 33, geçerli dizindeki tüm gizlenmemiş alt dizinlerin gizlenmemiş alt dizinlerindeki tüm gizlenmeyen dosyalar,UVC ve 3432.

Bu yüzden:

  1. Genişletme sırasında gerçekleştirilen sözcük ayırma veya dosya adı oluşturma istemediğiniz sürece, her zaman (çift tırnaklı) komut değiştirmeleri yapmalısınız.
  2. İstediğiniz yaparsanız kelime bölme , o zaman belirlesin $IFSüzerinde bölmek istediğiniz karaktere.
  3. Kelimenin bölünmesini ancak dosya adının oluşturulmasını istemiyorsanız , bunu set +fdevre dışı bırakmak için

Tek tırnak her şeyden alıntı yapar, bu nedenle backtick karakterlerinin tam anlamıyla alınmasına neden olur.

Örnek (kullanmak -x, neler olup bittiğini görmeyi kolaylaştırır):

$ 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

Çıktı NUL karakterleri içeriyorsa, davranış kabuktan kabuğa değişir: bazıları bunları kaldırır, bazıları çıktıyı ilk NUL karakterinde keser, zshkorur , ancak yine de harici komutların NUL'ları içeren argümanları alamayacağını unutmayın.


Gerçek bir "POSIX kabuğu" diye bir şey yoktur. İşlevselliklerinin sınırlı bir alt kümesini kullanarak ilgili çeşitli POSIX standartlarına uyan kabukları vardır.
fpmurphy

0

`Date` ile tarihin çıktısını birden fazla kelimeye alırsınız, çünkü kelime bölmesi komutun yerine getirilmesinden sonra yapılır.

"` Date` "ile tarihin çıktısını tek bir kelime / parametre olarak elde edersiniz, çünkü çift tırnak işaretleri arasında komut ikamesi vardır, ancak çıktı daha fazla ayrıştırılmaz. Aynısı, aşağıdaki örneğindeki "$ i" gibi değişken genişleme için de geçerlidir.

'`Date`' 'ile tam anlamıyla bir` date` elde edersiniz, çünkü tek tırnaklar arasında komut değişikliği yoktur.

Belki de 3 formun farklılıkları bu şekilde daha belirgin olacaktır:

> 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`
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.