Neden “echo -e” komutları doğru çıktıyı vermiyor?


21

Bu komutu yazarken Ubuntu 18.04 LTS terminalinde:

echo -e "Hello\\\n"

Bunu çıktı olarak verir:

Hello\n

Ancak man sayfasının dediği gibi yazmalıdır:

Hello\

Yani, önce yazdır Hello, sonra \, sonra bir yeni satır karakteri (ve sonra başka bir yeni satır). Sorun nerede?

Bu birkaç echo -ekomutu ve bunların çıktısını görün :

man420@man420-X542UQ:~$ echo -e "HEllo\a\a\a\a\a\a\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\a\\\n"
HEllo\n

yes.for ilk 2 \ gerektiği çıkışı \ .ve son \ n \ o Hello yazdırmak neden .bu bir ters eğik çizgi kaçış \ n (yeni satır) yapmak
yolin00

1
Tırnaklar olmadan deneyin.
ajgringo619

2
Eliah Kagan tarafından kabul etmeniz gereken şaşırtıcı bir cevap vardı.
vanadyum

2
Kullanmayın echoilk etapta: kullanılmasını printf.
chepner

2
Yazdığınız şeyin tam olarak komutun argüman olarak iletildiğinden emin olmak istiyorsanız her zaman tek tırnak işareti kullanın.
Giacomo Alzetta

Yanıtlar:


29

Ters eğik çizgiler özel olarak işlenir echo -e, ancak önce kabuğun alıntı kurallarına göre , bazen özel olarak kabuk (bu durumda olan bash) ile işlenir .

Argüman echoaslında görür Hello\\n. Geçtiğiniz -eiçin echo, ters eğik çizgi kaçışlarını özel olarak ele alır ve \\teke doğru daraltılır \. Final nkaçamadı, bu yüzden tam anlamıyla görünüyor.

Bunun nedeni echo, kabuğun kendi işleminden\ önce ve ayrı olarak , kabuğun bazı bağlamlarda özel olarak işlem görmesidir, ancak diğerleri değildir. Tırnaksız \karakterler her zaman özel olarak işlenir, tek tırnak \ asla özel işlem yapılmaz, ancak koştuğunuz komuttaki gibi çift ​​tırnaklı \ karakterlerin işlenmesi daha ince ve karmaşıktır.

Kabuk bir komutta çift tırnaklı metinle karşılaştığında, olduğu gibi "Hello\\\n", aksi halde değil,\ çift ​​tırnak işaretleri içinde özel bir anlamı olabilecek bir karakterden önce gelen bir kaçış karakteri gibi davranır .

  1. Çünkü \bazen özel bir anlam içini vardır "", bir \hemen başka öncesinde \bu ikinci alıntı etkisine sahiptir \. Böylece çift tırnak içinde, ilk \\içine çöktü \.
  2. Bu ilk iki \karakterden sonra , ilk iki karakterden \etkilenmeyen ve bir karakterden önce gelen üçüncü bir karakter vardır n. Ancak n, çift tırnak işaretleri içinde özel olarak işlenen bir karakter değildir, bu yüzden \bu durumda özel olarak işlenmeden önce. Böylece \nkalır \n.

Etkisi, çift tırnak içinde, \\\nolarak yorumlanır \\n.

echo -eGörüldüğü zaman \\n, birincisi \ikinciden özel bir anlam çıkarır, bu yüzden bu metin için kelimenin tam anlamıyla echobasar \n.


Amacınız Hellofazladan bir yeni satırla yazdırmak , ancak ters eğik çizgi içermemekse (soru aslında bu konuda belirsizdi, artı yararlı bir örnek olduğunu düşünüyorum), o zaman bir çözüm a'yı kaldırmaktır \. echo -e "Hello\\n"Çıkışları Hello, sonunda yeni bir satırsonuyla çalıştırın .

Tek tırnak kullanmak ve yazmak daha iyi bir çözümdür echo -e 'Hello\n'. Tek tırnak, en güçlü alıntı şeklidir. Çok daha iyi bir çözüm kullanımına genellikle printfyerine echobu durumda olurdu printf 'Hello\n\n'.

Amacınız Hello\ters eğik çizgiyi ve ardından fazladan bir yeni satırı izlemektir. O zaman çift alıntı yaklaşımı mümkündür ancak hantaldır. :, İş geriye doğru anlamaya echo -edönüştürür \\için \ve \nbir satır için, ve çift alıntı dönüştürür \\için \altı ters eğik (ile yapabilirsiniz böylece echo -e "Hello\\\\\\n") çünkü \\niçine dönüşler \nnedeniyle bir ters eğik çizgi başka kaçan. Çift alıntı korur çünkü aynı zamanda, beş ile yapabilirsiniz \nzaman \kaçmaz.

Bu, tekli fiyatlandırmanın faydasını gösterir: sadece echo -etekli tırnak ( echo -e 'Hello\\\n') içine görmek istediğiniz şeyi koyun . printfburada da iyidir. Bir seçenek var printf 'Hello\\\n\n'. Ancak, printfgerçekten parladığı yer, ek argümanlar ekleyebilmenizdir. Bunun yerine printf '%s\n\n' 'Hello\'ikinci argümanı ekleyen kullanabilirsiniz (kelimenin tam anlamıyla Hello\çünkü tek tırnaklar hiçbir şeyi değiştirmez) %s.

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.