Bisakah seseorang menjelaskan apa yang terjadi di balik layar dalam karakter melarikan diri di shell Linux? Saya mencoba yang berikut ini dan sering googled, tanpa berhasil memahami apa (dan bagaimana) yang terjadi:
root@sv01:~# echo -e "\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\\ Hello!"
\\\ Hello!
root@sv01:~# echo -e "\n Hello!"
Hello!
root@sv01:~# echo -e "\\n Hello!"
Hello!
root@sv01:~# echo -e "\\\n Hello!"
\n Hello!
Saya benar-benar tersesat di sana, jadi misalnya, mengapa tiga garis miring terbalik hanya memberikan satu tebasan belakang? Saya berharap: dua yang pertama akan lolos ke satu, yang ketiga tidak akan menemukan apa pun untuk melarikan diri sehingga akan tetap menjadi garis miring (garis dalam percobaan pertama), tetapi yang terjadi adalah bahwa yang ketiga hilang begitu saja.
Mengapa saya mendapatkan satu backslash dari empat \\\\ Hello
? Saya berharap setiap pasangan akan memberikan satu tebasan -> dua garis miring terbalik.
Dan mengapa saya perlu tiga backslash dalam kasus terakhir untuk bisa lolos? apa yang terjadi di latar belakang melarikan diri untuk mendapatkan itu? dan apa bedanya dengan \\n
case?
Saya menghargai penjelasan apa pun yang terjadi di baris sebelumnya.
echo -e
perilaku bukanlah standar yang ditentukan - lihat pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html . Keluaran sepenuhnya ditentukan oleh implementasi jika ada backslash literal di mana saja dalam input, dan satu-satunya opsi yang diizinkan adalah-n
(artinya implementasi yang sesuai standar akanecho -e
mencetak-e
pada outputnya).echo -e
tidak aman:echo
akan berperilaku sesuai dengan standar jika keduanyaposix
danxpg_echo
opsi runtime diaktifkan, atau jika dikompilasi dengan opsi waktu-bangun yang setara. Praktik yang aman adalah menggunakanprintf
sebagai gantinya - lihat bagian APLIKASI PENGGUNAAN dan RATIONALE dari tautan di atas yang menjelaskan cara menjadikanprintf
tindakan sebagai penggantiecho
.Jawaban:
Ini karena
bash
danecho -e
digabungkan. Dariman 1 bash
Intinya adalah: backslash yang dikutip ganda tidak selalu spesial.
Ada berbagai implementasi
echo
pada umumnya, ini adalah builtin inbash
; yang penting di sini adalah perilaku ini:Sekarang kita dapat memecahkan kode:
echo -e "\ Hello!"
- tidak ada yang istimewabash
, tidak ada yang istimewa untukecho
;\
tetap.echo -e "\\ Hello!"
- Yang pertama\
mengatakanbash
untuk memperlakukan yang kedua\
secara harfiah;echo
dapatkan\ Hello!
dan bertindak seperti di atas.echo -e "\\\ Hello!"
- Yang pertama\
mengatakanbash
untuk memperlakukan yang kedua\
secara harfiah;echo
mendapat\\ Hello!
dan (karena-e
) itu diakui\\
sebagai\
.echo -e "\\\\ Hello!"
- Yang pertama\
mengatakanbash
untuk memperlakukan yang kedua\
secara harfiah; yang ketiga mengatakan hal yang sama tentang yang keempat;echo
mendapat\\ Hello!
dan (karena-e
) itu diakui\\
sebagai\
.echo -e "\\\\\ Hello!"
- Yang pertama\
mengatakanbash
untuk memperlakukan yang kedua\
secara harfiah; yang ketiga mengatakan hal yang sama tentang yang keempat; yang terakhir tidak spesial;echo
mendapat\\\ Hello!
dan (karena-e
) ia mengenali inisial\\
sebagai\
, yang terakhir\
tetap utuh.Dan seterusnya. Seperti yang Anda lihat, hingga empat garis miring terbalik berturut-turut memberikan satu dalam hasil. Itu sebabnya Anda perlu (setidaknya) sembilan dari mereka untuk mendapatkan tiga. 9 = 4 + 4 + 1.
Sekarang dengan
\n
:echo -e "\n Hello!"
- tidak ada yang istimewabash
, gema mendapatkan string yang sama dan (karena-e
) ia mengartikan\n
sebagai baris baru.echo -e "\\n Hello!"
-bash
menafsirkan\\
sebagai\
;echo
dapatkan\n Hello!
dan hasilnya sama seperti di atas.echo -e "\\\n Hello!"
-bash
Menafsirkan inisial\\
sebagai\
;echo
mendapat\\n Hello!
dan (karena-e
) mengartikannya\\
sebagai literal\
yang perlu dicetak.Hasilnya akan berbeda dengan
'
bukan"
(karenabash
perilaku yang berbeda ) atau tanpa-e
(echo
perilaku yang berbeda ).sumber
-e
menilai teks yang sudah dinilai oleh bash, benarkah itu? jika itu benar, itu menghilangkan kebingungan. Bisakah Anda menyebutkan bagaimanased
berperilaku? apakah ia memiliki teknik pelariannya sendiri? jadi maksud saya apakah itu berperilaku seperti gema-e
?sed
. Anda dapat mengajukan pertanyaan lain (sed
hanya tentang ), lakukan penelitian Anda sendiri terlebih dahulu.sed
akan mengikuti prinsip-prinsip dasar yang sama: bash akan menginterpretasikan baris perintah sesuai dengan aturannya, mengurai (dan mungkin menghapus) tanda kutip dan lolos. Hasil itu diteruskansed
, yang menafsirkannya sesuai dengan aturan pelariannya. BTW, Anda dapat menyederhanakan ini dengan menggunakan string dengan tanda kutip tunggalbash
, karena itu tidak memiliki interpretasi melarikan diri dilakukan (oleh bash) - bash menghapus tanda kutip tunggal, dan meneruskan apa yang ada di dalamnya langsung ke perintah.echo -e "\\\n Hello!"
kasus ini. Di sini bash akan melarikan diri, dan itu akan menjadi\\n
, kemudian-e
akan lolos dari dua backslash yang dihasilkan\\n
dan kemudian mereka akan menjadi\n
. sekarang siapa yang mengartikan\n
untuk membuatnya menjadi baris baru? Biasanya dalam kasusecho -e "\n Hello!"
, bash tidak melakukan apa-apa, dan-e
menafsirkan\n
sebagai baris baru. tetapi dalam situasi yang disebutkan pertama proses penafsiran dilakukan sebelum\n
ditafsirkan. Bisakah Anda jelaskan itu?sed
yang membingungkanku tadi malam (mungkin aku melakukan sesuatu yang salah kemarin), tapi sekarang aku mencoba lagi sama denganecho -e
dansed
, dan saya mendapat hal yang sama seperti dikecualikan, terima kasih!