Bagaimana Anda lolos dari tanda kutip dalam string tunggal yang dikutip dalam bash?

18

Saya tidak mengerti bagaimana bash mengevaluasi keluarnya karakter apostrof dalam string yang dikutip tunggal.

Berikut ini sebuah contoh:

$ echo ''\''Hello World'\'''
'Hello World' # works

$ echo '\'Hello World\''
 > # expects you to continue input

Saya sudah mencoba mencari penjelasan untuk ini tetapi tidak bisa mendapatkan apa-apa. Apa yang dilakukan bash di sini?

Kibet
sumber
echo \''Hello World'\'
matematika

Jawaban:

19

Dalam tanda kutip tunggal, tidak ada pelarian yang mungkin terjadi. Tidak ada cara bagaimana memasukkan penawaran tunggal ke dalam penawaran tunggal. Lihat Mengutip dalam bash man .

choroba
sumber
1
Kamu benar. Caranya adalah di baris itu 'Sebuah kutipan tunggal mungkin tidak terjadi antara kutipan tunggal bahkan ketika didahului oleh backslash' Jadi itu mungkin membaginya menjadi bagian-bagian yang berbeda.
Kibet
@Colin Begitu kutipan tunggal ada di dalam dua kutipan tunggal lainnya (tapi terbalik), kutipan yang dikutip bukan kutipan nyata lagi. Itu hanya arang tanpa karakteristik pasangan khusus.
zero2cx
1
@ zero2cx: Tidak benar:echo '\''
choroba
@ zero2cx: Saya akan mengatakan "di luar" bukan "di dalam".
choroba
3
@choroba tidak "sepenuhnya" benar, dalam bash yang dapat Anda lakukanecho $'\'hello world\''
bufh
9

Selain kutipan tunggal dan ganda yang didukung POSIX, bashmenyediakan jenis kutipan tambahan untuk memungkinkan kelas kecil karakter yang lolos (termasuk kutipan tunggal) dalam string yang dikutip:

$ echo $'\'Hello World\''
'Hello World'

Lihat bagian KUTIPAN di bashhalaman manual, di dekat bagian akhir. (Cari "ANSI C".)

chepner
sumber
3

Untuk menjelaskan apa yang terjadi dengan tanda kutip Anda yang lolos, kami akan memeriksa contoh kedua Anda (juga lihat tanda kutip tunggal , atau tanda kutip kuat ):

$ echo '\'Hello World\''
>     # expects you to continue input

Di sini, Anda membiarkan kutip tergantung, seperti yang telah Anda nyatakan. Sekarang rapikan ujungnya dan ubah menjadi:

                     v                                v           v
$ echo '\'Hello World     # Echo two strings: '\' and 'Hello World'.
\Hello World         ^

Sub-string "Hello World" tidak dikutip di sini, tetapi berperilaku seolah-olah itu dikutip kuat. Dengan menggunakan contoh Anda lagi, rapikan ujungnya secara berbeda kali ini:

                     vv                                    v (plain apostrophe)
$ echo '\'Hello World\'   # Will echo: '\' and 'Hello World''
\Hello World'        ^^   # Note that the trailing ' char is backslash escaped. 

Sub-string "Hello World" lagi-lagi berperilaku seolah-olah dikutip kuat, dengan hanya tanda kutip ditambahkan (lolos, jadi tidak ada lagi kutipan tunggal) di akhir.

Ketika satu kutip tunggal ditambahkan pada bagian akhir (contoh asli Anda), string dibiarkan menggantung dan menunggu kutipan-dekat.

nol2cx
sumber
3

Contoh sederhana untuk menghindari kutip di shell:

$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc

Ini dilakukan dengan menutup yang sudah dibuka satu ( '), menempatkan satu lolos ( \') untuk mencetak, lalu membuka yang lain ( ').

Kalau tidak:

$ echo 'abc'"'"'abc'
abc'abc
$ echo "abc"'"'"abc"
abc"abc

Ini dilakukan dengan menyelesaikan yang sudah dibuka satu ( '), menempatkan kutipan di kutipan lain ( "'"), lalu membuka yang lain ( ').

Apa yang Anda lakukan ( '\'Hello World\''), adalah:

  1. Dibuka 1 apostrof: '.
  2. Ditutup tepat setelah itu \', sehingga string menjadi: '\'.
  3. Hello World bukan kutipan.
  4. Menempatkan apostrof mandiri ( \') tanpa membukanya.
  5. Apostrof terakhir ( ') adalah string pembuka, tetapi tidak ada penutup yang diharapkan.

Jadi contoh yang benar adalah:

$ echo \'Hello World\'
'Hello World'

Terkait: Bagaimana cara melepaskan tanda kutip tunggal dalam string tanda kutip tunggal?

kenorb
sumber