Örneğin, aşağıdaki komut çalışmaz:
if [[-e xyz]]; then echo File exists;fi
ksh aşağıdaki hatayı verir
[[-e: command not found
Bunun nedeni "[[-" belirsiz mi?
Örneğin, aşağıdaki komut çalışmaz:
if [[-e xyz]]; then echo File exists;fi
ksh aşağıdaki hatayı verir
[[-e: command not found
Bunun nedeni "[[-" belirsiz mi?
Yanıtlar:
En basit açıklama olurdu, çünkü kılavuzda öyle görünüyor [[ expression ]]ki [[ve arasında expressionve kapanışında boşluk olması gerekiyor ]]. Ama elbette daha derinlemesine bakmayı deneyebiliriz. Kabuklar biraz karmaşık gramerlere sahiptir ve "kelime bölme" kavramına büyük ölçüde güvenir. Özellikle, ksh (1) manuel durumları:
Kabuk girdisini sözcüklere bölerek ayrıştırmaya başlar. Karakter dizisi olan kelimeler, sıralanmamış boşluk karakterleri (boşluk, sekme ve yeni satır) veya meta karakterler (<,>, |,;, &, (ve)) ile sınırlandırılır. Kelimeler sınırlandırılmasının yanı sıra, boşluklar ve sekmeler yok sayılırken, yeni satırlar genellikle komutları sınırlar.
Bu yüzden kılavuzda belirtildiği gibi, karakter dizisi [[-ebir kabuk kelimesi olarak kabul edilir. kshyerleşik komutlar ve özel işleçler ( forveya gibi while) listesinde böyle bir komut arar, sonra harici bir komut arar - ve voilà - hiçbiri bulunamadı, dolayısıyla komutla ilgili bir hata iletisi var.
Bu durumda [[özel meta karakterler de yoktur. Eğer öyle olsaydı , içindeki -ekısım kendi başına [[-ebir argüman değil, bir kabuk kelimesi olarak kabul [[edilirdi. Bununla birlikte, [[bileşik komut olarak tanımlanır ve kılavuzda aşağıdakiler söylenir:
Bileşik komutlar, aşağıdaki ayrılmış sözcükler kullanılarak oluşturulur - bu sözcükler yalnızca tırnak işaretleri olmadan ve bir komutun ilk sözcüğü olarak kullanılırsa tanınır (yani, parametre atamaları veya yeniden yönlendirmelerden önce gelemezler):
Dolayısıyla, [[bir bileşik komut olarak tanınabilmesi için , bir komutun veya komut listesinin ilk sözcüğü olması gerekir; bu, daha önce bir "sözcük" tanımıyla, boşluklardan, sekmelerden veya diğer satırlardan yeni satırlarla ayrılması gerektiğini ima eder kelimeler / argümanlar.
Yorumlarda şunu sordunuz : "Ayrıştırıcı neden bulur bulmaz durmuyor" [["kalıbı ve bunu koşullu bir komutun başlangıcı olarak kabul ediyor?" Kısa cevap muhtemelen 1) [sözdiziminin etkisi aslında harici bir komut olduğu ve POSIX standart uyumluluğu için bugün bile harici komut olarak var olduğu ve 2) kabuk ayrıştırıcısı böyle oluşturulduğundan dolayıdır. Kabuk ayrıştırıcı, boşlukla sınırlandırılmış diğer özel karakterleri tanıyabilir: echo $((2+2))ve (echo foobar)mükemmel çalışır. Belki de gelecekte kshgelişim devam ettiğinde mkshveya pdkshbiri çatalsız veya klon gibi göründüğünde ( ya da gibi ) birisi boşluksuz sözdizimi uygulayacaktır [[-e.
[["ayrılmış sözcük" olarak adlandırılır (Kabuk Komut Dili'nin 2.9 bölümüne bakın ). POSIX tanımına göre, ayrılmış sözcük boşluklarla sınırlanmalıdır. Bunun aksine (, bir operatördür ve bölüm 2.9'daki "standart gösterimler, <blank>s'nin gerekli olmayacağı bazı yerlerde (belirteçlerden biri bir operatör olduğunda) belirteçler arasındaki boşluğu içerir ". İlgili tartışmaya bakın: POSIX Shell Gramer: Neden Brace Group'un İlk Boşluğa İhtiyacı Var Ama Subshell Gerekmiyor?char, bir anahtar kelimedir, ancak yine de charsomeletter = 'A';ayrıştırıcıyı gördükten sonra yazamaz ve durmasını bekleyemezsiniz char.
i--<=++jve derleyicinin bunu ayrıştırma sorunu yoktur i -- <= ++ j.
_). Ksh (bir operatör olarak vardır ve (echo hello)ayrıştırır ( echo hello ). Bu gelmiştir if, {, [[ve diğer anahtar kelimeler ve ifx, {xve [[xher biri belirteci olan - nasıl böyle charsomeletterbir C belirteci olduğunu. Buna karşılık, (xksh'ta sıralanmamış iki simge - i--C'deki iki simge gibi. Bir operatör olmanın kavramsal olarak bile anlamı Bourne tarzı mermiler (ksh gibi) ve C arasında farklılık gösterir. Ancak Peter A. Schneider bir gerçek sözcüksel benzerlik.
Dikkat edilmesi gereken önemli olan [bir komuttur ve [[bash ve ksh içindeki shell anahtar sözcüğünü temel alır [.
[[ile benzer şekilde kullanılır [. Bazen hatta yerini alabilir [ ]ile [[ ]]davranışında hiçbir değişiklik olmadan. İle [, herhangi bir komuta gibi, bir uzay komuta ve argümanları arasında zorunludur. Aynı şey için de geçerlidir [[.
Eskiden sadece vardı /usr/bin/[. Artık çoğu mermi [verimlilik için inşa edilmiştir - ancak sözdizimi aynıdır. Sağlayan mermilerde, daha çok yönlü bir alternatif [[olarak işlev görür .[
İşte [bash için açıklama :
$ help [
[: [ arg... ]
Evaluate conditional expression.
This is a synonym for the "test" builtin, but the last argument must
be a literal `]', to match the opening `['.
Yani [eşdeğerdir test( ]en sonunda bir argüman beklemek dışında ). help testüzerinde daha fazla ayrıntı verecek. Bunu ile karşılaştırabilirsiniz help [[.
Harici komut için bir kılavuz sayfası da vardır [( man \[).
Bu durumuda
if [[-e
[de [[orada. Tam kelime [[-e.if [[-edoğru / yanlış testi yapar. Peki bir komut [[-evar mı? Bunun nedeni "[[-" belirsiz mi?
Evet. Ya da hayır. [[-ene olduğu: kabuğun anladığı hiçbir şey, bu yüzden kendi emri olduğunu varsayar. ;-)
[[-epotansiyel olarak geçerli (garip görünüyorsa) bir komut adıdır.
Alan bir sınırlayıcıdır ve gereklidir. Gördüğünüz gibi shellcheck:
$ shellcheck gmail-browse-msgs-algorithm.sh
In gmail-browse-msgs-algorithm.sh line 847:
[[$Today != "${DaysArr[ i + DAY_DELETED_ON_NDX ]}" ]] && continue
^-- SC1035: You need a space after the [[ and before the ]].
(Hem ksh hem de bash desteği vardır [[ve boşluk olmadan çalışmaz. Shellcheck tam olarak bu satırı içeren benzer ksh ve bash komut dosyalarıyla çıktı verir.)
Sınırlayıcılara neden ihtiyaç duyulduğunu belirteçler ve sözlükçelerle ilişkilendirmek gerekir .
kshsoruda kabuk hakkında sordu . Bash ödünç [[gelen operatörü kshve onların davranışları aynıdır bu soruda, ancak arasında bazı önemli farklılıklar var gibi ben varsayımların temkinli olacağını kshve bashdavranış ve iç yapıları. Bunun nedeni, shellcheck'in bash betiği üzerinde çalışması nedeniyle, ksh betikleri için uygun bir araç olmayabilir. Farklı kabuklara yaklaşırken akılda tutulması gereken bir şey
[[kuralları vurgulamak için shellcheck kullanarak fırsatçı oluyordum . Hiçbir şekilde bunun hata bulabilen kshbir kabuk olduğu anlamını yitirmedim shellcheck. Umarım başkaları takdir eder kshve bashiki farklı tercümandır. Bundan bahsettiğiniz için teşekkürler. Ayrıca , harici bir komut [[iken inşa edilmiş bir bash da dikkat çekicidir [.
[bash yerleşik bir :) :) manpages.ubuntu.com/manpages/bionic/man7/bash-builtins.7.html Ama çok uzakta değilsiniz - [veya testharici bir komut olması gerekiyor. Orijinal Bourne kabuğunun günlerinde [aslında harici bir komut vardı ve günümüzde hala /usr/bin/[POSIX bunun harici bir komut olmasını gerektirdiği için var. Pubs.opengroup.org/onlinepubs/009695399/utilities/test.html POSIX için çok az şey gerekiyor yerleşik pubs.opengroup.org/onlinepubs/009695399/idx/sbi.html Yerleşiklik [verimlilik içindir
ksh; bir hashbang kullanın veya -s ksh. Btw, ksh ve bash [["yerleşik", ancak aksine , bir kabuk yerleşik olan bir anahtar kelime . (ksh :; bash :) Yerleşikler ve harici komutlar sözdizimsel olarak birbirine benzer. Tek yönlü gelen farklılık olduğunu kadar - bir yerleşiğini olarak olamazdı Bağımsız değişkenlerinin, içinde bastırır bazı açılımlar gruplama yapamadık bunun bir yerleşik idi. Bu (veya ) bir token olmanın garip hissetmesinin nedeni olabilir . Bence buildins ve anahtar kelimelerin sözcüksel ama sözdizimsel olarak benzer olmadığını söylemek doğru . @SergiyKolodyazhnyy[whence -v [ [[type [ [[[[[[[{{x[[x
[[harici bir komut olabilir! Yani, bir program olabilir ve kabuğunuz tarafından doğrudan desteklenen bir sözdizimi olmayabilir. Boşluksuz bir sözdizimini desteklemek mümkün olabilir, kshancak harici sistemlerde başarısız olur, [[bu nedenle uyumluluk nedeniyle gerekli alanı tutmak daha iyidir.
[[Mesela BusyBox harici bir komut sağlıyor .
İtibaren [[-ekabuk genişleme katılabilir (bu gibi kullanılabilir
echo [[-e]*
arasında [ve edahilinde bir harfle başlayan tüm dosyaları listelemek için ), normal boşluklarla yönetilen kelime bölünmesine katılmayan özel karakterler olsaydı [ve tam bir karmaşa olurdu ].
[[bir anahtar kelimedir - muhtemelen kabuğun ayrıştırma ağacı, anahtar kelimelerin boşlukla tanımlanmasını gerektirir