Kadang-kadang saya melihat script menggunakan semua cara-cara yang berbeda mengutip beberapa teks: "..."
, '...'
, $'...'
, dan $"..."
. Mengapa ada begitu banyak jenis kutipan yang digunakan?
Apakah mereka berperilaku berbeda atau memengaruhi apa yang dapat saya lakukan di dalamnya?
Jawaban:
Semua ini berarti sesuatu yang berbeda, dan Anda dapat menulis hal-hal yang berbeda di dalamnya (atau hal yang sama, dengan makna berbeda). Berbagai jenis kutipan menafsirkan urutan pelarian yang berbeda di dalamnya (
\something
), atau melakukan atau tidak mengizinkan interpolasi variabel ($something
) dan jenis ekspansi lainnya di dalamnya.Pendeknya:
'...'
sepenuhnya literal."..."
memungkinkan kedua variabel dan karakter kutipan yang disematkan.$'...'
melakukan pelarian karakter seperti\n
, tetapi tidak memperluas variabel.$"..."
adalah untuk terjemahan bahasa manusia dalam Bash dan ksh.'Kutipan tunggal'
Apa pun yang Anda tulis di antara tanda kutip tunggal diperlakukan secara harfiah dan tidak diproses sama sekali. Tanda garis miring terbalik dan tanda dolar tidak memiliki arti khusus di sana. Ini berarti Anda tidak dapat melepaskan diri dari karakter (termasuk tanda kutip tunggal lainnya!), Menginterpolasi variabel, atau menggunakan fitur shell lainnya.
Semua contoh ini menghasilkan apa yang tertulis di antara kutipan:
Yang terakhir rumit - ada dua string yang dikutip tunggal dijalankan bersama dengan beberapa teks yang tidak dikutip. Yang pertama berisi
I\
. Teks yang tidakdn\'t
dikutip mengandung satu kutipan yang lolos pada level shell , sehingga tidak memulai string yang dikutip dan dimasukkan sebagai karakter literal (jadi,dn't
). String terakhir yang dikutip adalah adilve
. Semua itu dijalankan bersama menjadi satu kata dengan cara yang biasa shell bekerja.Idiom yang agak umum untuk menggabungkan teks dan variabel literal adalah menjalankannya bersama seperti itu:
akan menghasilkan
sebagai satu kata (yang lebih baik untuk double-quote
$PATH
juga hanya dalam kasus - spasi atau globbing karakter dalam variabel nilai dapat diproses sebaliknya - tapi demi contoh berjalan dibaca saya belum)."Kutipan ganda"
Di dalam tanda kutip ganda, dua jenis ekspansi diproses, dan Anda dapat menggunakan garis miring terbalik untuk menghindari karakter untuk mencegah ekspansi atau lolos dari diproses.
Ada dua kategori ekspansi yang terjadi di dalam tanda kutip ganda:
$
( ekspansi parameter$abc
dan${abc}
, substitusi perintah$(...)
, dan ekspansi aritmatika$((...))
);`abc`
;Di dalam tanda kutip, garis miring terbalik dapat menghambat mereka ekspansi dengan menempatkan sebelum
$
atau`
. Itu juga dapat menghindari kutip ganda penutupan, jadi\"
termasuk saja"
dalam string Anda, atau backslash lainnya. Setiap backslash lainnya dipertahankan secara literal - tidak ada jalan keluar untuk menghasilkan karakter lain, dan itu tidak dihapus.Beberapa contoh ini bertindak berbeda dari sebelumnya, dan beberapa tidak:
$ 'Kutipan ANSI-C'
Jenis kutipan ini memungkinkan backslash C-style untuk diproses, tetapi bukan variabel atau substitusi yang disematkan. Ini satu - satunya jenis kutipan yang mendukung pelarian karakter .
Ini adalah ekstensi dari ksh, sekarang didukung di Bash, zsh, dan beberapa shell lainnya juga. Ini belum menjadi bagian dari standar POSIX dan skrip portabel yang maksimal tidak dapat menggunakannya, tetapi skrip Bash atau ksh bebas untuk menggunakannya.
Semua lolos ini dapat digunakan dengan arti C mereka:
\a
,\b
,\f
,\n
,\r
,\t
,\v
, dan lolos literal\\
,\'
,\"
, dan\?
. Mereka juga mendukung ekstensi\e
(karakter escape) dan dalam Bash dan ksh\cx
(apa yang akan dimasukkan oleh Ctrl-x , misalnya\cM
carriage return). Shell memiliki serangkaian ekstensi kecil sendiri.Ini juga memungkinkan empat jenis karakter generik lolos:
\nnn
, satu byte dengan nilai oktal nnn\xHH
, satu byte dengan nilai heksadesimal HH\uHHHH
, titik kode Unicode yang indeks heksadesimalnya adalah HHHH\UHHHHHHHH
, titik kode Unicode yang indeks heksadesimalnya adalah HHHHHHHHSemua digit itu adalah opsional setelah yang pertama.
$
dan`
tidak memiliki makna dan dipertahankan secara harfiah, sehingga Anda tidak dapat memasukkan variabel di sana.Sebagian besar lolos ini Anda dapat mensimulasikan menggunakan satu
printf
perintah , meskipun POSIX hanya membutuhkan\\
,\a
,\b
,\f
,\n
,\r
,\t
,\v
, dan\nnn
untuk bekerja di sana. Anda dapat menggunakan substitusi perintah untuk menanamkanprintf
tanda kutip ganda dalam jika diperlukan:"Path:$(printf '\t')$PATH"
.$ "Terjemahan lokal"
Ini adalah ekstensi spesifik ksh dan Bash untuk string tekstual bahasa alami yang melokalisasi, dan mencari bagian di dalam tanda kutip dalam katalog pesan. Ia melakukan semua ekspansi kuotasi ganda terlebih dahulu. Jika string tidak ditemukan dalam database terjemahan, itu digunakan sebagai terjemahannya sendiri. Asumsi bawaan adalah bahwa string adalah dalam bahasa Inggris.
Anda mungkin tidak ingin menggunakan yang ini, tetapi jika Anda melihatnya, Anda biasanya dapat memperlakukannya sebagai tanda kutip ganda biasa.
Satu hal yang perlu diperhatikan adalah tidak ada jenis kutipan yang memungkinkan perluasan parameter tertanam dan karakter tertanam lolos. Dalam kebanyakan kasus di mana Anda menginginkannya, Anda akan lebih baik (lebih aman) menggunakan
printf
:Ini dengan jelas memisahkan bagian mana yang dapat lolos dari karakter dan mana yang merupakan nilai data.
Lain adalah bahwa semua gaya mengutip membuat satu "kata" di shell, kecuali
$@
atau ekspansi array${x[@]}
digunakan di dalam tanda kutip ganda. Kedua bentuk kutipan tunggal selalu satu kata dan tidak pernah berkembang lebih jauh.sumber
$"..."
juga dari ksh93, ditambahkan ke bash di 2.0.\cX
dizsh
. Itu\CX
atau di\C-X
sana (\c
sudah memiliki arti khususecho
)'let x="'$PATH\"
salah dalam konteks daftar di shell selainzsh
seperti$PATH
yang tidak dikutip (jadi akan dikenakan split + glob yang tidak Anda inginkan di sini).