Jawaban:
`date` hanya akan diperluas ke output dari date
perintah. Namun, ini menghilangkan karakter spasi tambahan di tempat-tempat di mana ada lebih dari satu karakter spasi berturut-turut dalam output. (Ini karena substitusi perintah tunduk pada pemisahan kata, dan karena bagaimana echo
perintah menangani beberapa argumen.)
Dalam "` tanggal` " , tanda kutip ganda adalah tanda kutip yang lemah, sehingga mereka akan memperluas variabel (coba" $ PWD ") dan melakukan substitusi perintah. Hasil ekspansi dilewatkan sebagai argumen tunggal ke echo
perintah, dengan spasi berurutan termasuk: yaitu, pemisahan kata tidak dilakukan.
Dalam '`tanggal`' , tanda kutip tunggal adalah tanda kutip yang lebih kuat, sehingga mereka tidak akan mengizinkan perluasan variabel atau substitusi perintah di dalamnya.
Lihat tautan ini untuk penjelasan lebih lanjut.
Mengedit poin pertama sebagaimana ditunjukkan dengan benar oleh Michael Suelmann dalam komentar di bawah ini .
date
perintah telanjang .
Kedua
echo `date`
dan
echo "`date`"
akan menampilkan tanggal. Output dari yang terakhir terlihat seperti output dari berjalan date
dengan sendirinya.
Namun, ada perbedaan: orang yang dikelilingi "
tanda kutip "
akan dikirim ke echo
sebagai argumen tunggal. Kutipan merangkum output dari seluruh perintah sebagai satu argumen. Karena echo
hanya mencetak argumennya secara berurutan, dengan spasi di antaranya, pada dasarnya akan terlihat sama.
Berikut adalah contoh perbedaan halus:
echo `date`
menghasilkan:
Fri Nov 1 01:48:45 EST 2013
tapi:
echo "`date`"
menghasilkan:
Fri Nov 1 01:48:49 EST 2013
Perhatikan bahwa dua spasi setelah Nov
dikurangi menjadi satu tanpa tanda kutip. Ini karena shell mengurai setiap elemen yang dipisahkan ruang dan mengirimkan hasilnya ke echo sebagai 6 argumen. Saat Anda mengutipnya, gema menerima satu argumen tunggal dan kutipannya tetap mempertahankan ruang.
Ini menjadi jauh lebih penting dalam perintah selain gema. Sebagai contoh, bayangkan sebuah perintah foo
yang menginginkan dua argumen: tanggal, dan alamat email.
Ini akan berfungsi dalam skenario itu:
foo "`date`" joeuser@example.com
Tetapi ini akan membingungkan skrip dengan mengirimkannya 7 argumen:
foo `date` joeuser@example.com
Dalam kerang POSIX, `date`
adalah bentuk kuno dari substitusi perintah. Sintaks modernnya adalah $(date)
.
Dalam kedua kasus, mereka memperluas ke output date
dengan karakter garis belakang tertinggal (asalkan output tidak mengandung karakter NUL).
Namun, ketika tidak berada dalam tanda kutip ganda dan dalam konteks daftar (misalnya dalam argumen untuk perintah sederhana seperti echo
dalam kasus Anda), ekspansi tersebut selanjutnya tunduk pada:
Pemisahan kata : yaitu "keluaran dari date
karakter baris baru yang diluruskan" dipisah sesuai dengan nilai $IFS
variabel saat ini (secara default berisi spasi, tab dan baris baru (dan NUL dengan zsh
)) menjadi beberapa kata .
Misalnya, jika date
output Fri 1 Nov 14:11:15 GMT 2013\n
(seperti yang sering terjadi dalam lokal bahasa Inggris dan zona waktu British daratan), dan $IFS
saat ini berisi :
, yang akan dibagi menjadi 3 kata : Fri 1 Nov 14
, 11
dan 15 GMT 2013
.
zsh
): yaitu, setiap kata yang dihasilkan dari pemecahan atas mencari karakter wildcard ( *
, ?
, [...]
meskipun beberapa kerang memiliki lebih), dan diperluas untuk daftar nama file yang cocok dengan pola tersebut. Misalnya, jika output dari date
ini ?%? 33 */*/* UVC 3432
(seperti itu sering di lokal Venus dan UVC zona waktu), dan $IFS
adalah nilai default), maka yang mengembang ke semua non-tersembunyi 3 nama file karakter dalam direktori saat ini yang karakter tengah adalah %
, 33
, semua file yang tidak tersembunyi di semua subdirektori tidak tersembunyi dari semua subdirektori tidak tersembunyi dari direktori saat ini, UVC
dan 3432
.Itulah mengapa:
$IFS
karakter yang ingin Anda bagi.set +f
untuk menonaktifkannya.Kutipan tunggal mengutip semuanya sehingga menyebabkan karakter backtick diambil secara harfiah.
Contoh (menggunakan -x
membuatnya lebih mudah untuk melihat apa yang terjadi):
$ 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
Jika output berisi karakter NUL, maka perilaku bervariasi dari shell ke shell: beberapa menghapusnya, beberapa memotong output pada karakter NUL pertama, zsh
mempertahankannya tetapi perhatikan bahwa bagaimanapun perintah eksternal tidak dapat mengambil argumen yang berisi NUL
Dengan `date` Anda mendapatkan hasil split tanggal menjadi beberapa kata, karena pemisahan kata dilakukan setelah substitusi perintah.
Dengan "` date` "Anda mendapatkan output tanggal sebagai satu kata / parameter karena ada substitusi perintah antara tanda kutip ganda, tetapi hasilnya tidak diuraikan lebih lanjut. Hal yang sama berlaku dengan ekspansi variabel seperti "$ i" pada contoh saya di bawah ini.
Dengan '`date`' Anda mendapatkan` date` literal karena tidak ada substitusi perintah antara tanda kutip tunggal.
Mungkin perbedaan dari 3 bentuk akan lebih terlihat seperti ini:
> 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`