Ö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 expression
ve 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 [[-e
bir kabuk kelimesi olarak kabul edilir. ksh
yerleşik komutlar ve özel işleçler ( for
veya 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 -e
kısım kendi başına [[-e
bir 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 ksh
gelişim devam ettiğinde mksh
veya pdksh
biri ç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--<=++j
ve 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
, {x
ve [[x
her biri belirteci olan - nasıl böyle charsomeletter
bir C belirteci olduğunu. Buna karşılık, (x
ksh'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 [[-e
doğru / yanlış testi yapar. Peki bir komut [[-e
var mı? Bunun nedeni "[[-" belirsiz mi?
Evet. Ya da hayır. [[-e
ne olduğu: kabuğun anladığı hiçbir şey, bu yüzden kendi emri olduğunu varsayar. ;-)
[[-e
potansiyel 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 .
ksh
soruda kabuk hakkında sordu . Bash ödünç [[
gelen operatörü ksh
ve 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ı ksh
ve bash
davranış 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 ksh
bir kabuk olduğu anlamını yitirmedim shellcheck
. Umarım başkaları takdir eder ksh
ve bash
iki 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 test
harici 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, ksh
ancak 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 [[-e
kabuk genişleme katılabilir (bu gibi kullanılabilir
echo [[-e]*
arasında [
ve e
dahilinde 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