Bash'in zarif sadeliği, büyük adam sayfasında kayboluyor gibi görünüyor.
Yukarıdaki mükemmel çözümlere ek olarak, bash'ın ifadeleri nasıl ayrıştırıp yorumladığı konusunda size bir hile sayfası vermeye çalışacağımı düşündüm . Sonra bu yol haritasını kullanarak, neden amaçlanan şekilde çalışmadıklarını daha iyi anlamanıza yardımcı olmak için sorgulayıcı tarafından sunulan örnekleri inceleyeceğim.
Not: Kabuk betiği satırları doğrudan kullanılır. Yazılan giriş satırları ilk önce genişletilir.
Her bash çizgisi ilk önce tokenize edilir veya bir başka deyişle belirteçler olarak adlandırılan şeye doğrar . (Tokozlama, parantez, tilde, parametre, komut, aritmetik, işlem, sözcük bölme ve dosya adı genişletme dahil olmak üzere, diğer tüm genişlemeden önce gerçekleşir.)
Burada bir belirteç, giriş satırının bu özel meta karakterlerden biriyle ayrılmış (ayrılmış) bir kısmı anlamına gelir:
space, - White space...
tab,
newline,
‘<’, - Redirection & piping...
‘|’,
‘>’
‘&’, - And/Both < | > | >> .or. &<file descriptor>
‘;’, - Command termination
‘(’, - Subshell, closed by - ‘)’
Bash başka birçok özel karakter kullanıyor, ancak yalnızca bu 10' ilk belirteçleri üretiyor.
Ancak bu meta karakterlerin bazen bir belirteç içinde kullanılması gerektiğinden, özel anlamlarını almanın bir yolu olması gerekir. Buna kaçan denir. (Yani bir veya daha fazla bir dizi karakter alıntı yaparak ya yapılır Kaçan 'xx..'
, "xx.."
) veya bir arka eğik çizgi (yani tek bir karakteri adýnýnönüne \x
). (Bundan biraz daha karmaşık çünkü alıntıların da alıntılanması gerekiyor ve çift tırnakların her şeyi alıntılamadığı için, ancak bu sadeleştirme şimdilik yapacak.)
Bash alıntılarını, diğer dillerde olduğu gibi bir metin dizisinden alıntı yapma fikri ile karıştırmayın. Bash içindeki alıntılar arasındakiler karakter dizileri değil, giriş satırının meta karakterlerinden kaçan bölümleridir, böylece belirteçleri sınırlandırmazlar.
Dikkat, '
ve arasında önemli bir fark var "
, ancak bu başka bir gün için.
Kalan çıkmamış meta karakterler daha sonra belirteç ayırıcılar haline gelir.
Örneğin,
$ echo "x"'y'\g
xyg
$ echo "<"'|'\>
<|>
$ echo x\; echo y
x; echo y
İlk örnekte, bir alan sınırlayıcı tarafından üretilen iki simge vardır: echo
ve xyz
.
Aynı şekilde 2. örnekte.
Noktalı kaçan üçüncü örnekte, bu nedenle bir boşluk ayırıcı tarafından üretilen 4 belirteçleri vardır echo
, x;
, echo
ve y
. İlk belirteç daha sonra komut olarak çalıştırılır ve sonraki üç belirteçleri girdi olarak alır. 2. echo
çalıştırılmadığına dikkat edin.
Hatırlanması gereken önemli şey kaçan karakterler için bu bash ilk görünüyor olduğunu ( '
, "
ve \
) ve sonra bu sırayla, kaçış meta karakter sınırlayıcı arar.
Kaçmazsa, bu 10 özel karakter token
sınırlayıcı olarak işlev görür . Bazılarının ek anlamı da var, ama her şeyden önce belirteç sınırlayıcıları.
Grep ne bekler
Grep'in Yukarıdaki örnek bu belirteçleri ihtiyaç olarak, grep
, string
, filename
.
Sorunun ilk denemesi şuydu:
$ grep (sonra | orada) xx
Bu durumda (
, )
ve |
çıkış kullanılmayan meta karakterler ve böylece bu jeton içine girdi bölmek hizmet: grep
, (
, then
, |
, there
, )
, ve x.x
. grep görmek istiyor grep
, then|there
ve x.x
.
Sorunun ikinci denemesi şuydu:
grep "(sonra | orada)" xx
Bu içine sıfırlar grep
, (then|there)
, x.x
. Eğer yankı için grep çıkarırsanız bunu görebilirsiniz:
echo "(sonra | orada)" xx
(sonra | orada) xx