Sıra, bu bash komutlarının yürütülmesinde neden önemlidir?


10

Bash kabuğu ile ilgili anlayamadığım bir tutarsızlık var gibi görünüyor.

Eğer yürütürsem:

ls;date;time

üç sorgunun sonuçları sırayla gösterilir.

Ancak, değiştirilen tarih ve saat konumunda bir hata mesajı görüntülenir.

Eğer yürütürsem:

ls;time;date

Hata mesajı şöyle diyor: bash: syntax error near unexpected token 'date'.

Birisi bunu açıklayabilir mi?


Senin sorunun time;datevs yatıyor date;time. Bu boru hattı bashve timeçıktı ile üretilen son karakter ile ilgili bir sorun gibi görünüyor . Farklı terminal öykünücülerinde test edilen sonuçlar şunlardır: - [Bash] $ tarih; saat # [Tamam] $ saat; tarih # [ NotOK ] bash: beklenmedik jetonun yanında sözdizimi hatası `tarih '$ saat # yalnızca hata görünmüyor herhangi bir tarihin sonucu. - [Csh] $ tarih; saat # [Tamam] $ saat; tarih # [Tamam] - [Tcsh] $ tarih; saat # [Tamam] $ saat; tarih # [Tamam] - [Ksh] $ tarih; saat # [ Tamam] $ zaman; tarih # [Tamam]
Mostafa Shahverdy

Cevabımı hata mesajı için bir açıklama ile güncelledim. Lütfen aradığınız yanıtın bu olduğunu kontrol edin.
zwets

Yanıtlar:


10

timeSenin boru hattı komut değil /usr/bin/timeikili, fakat bash timeyerleşik. Karşılaştırma man timeile help time. Gördüğünüz hata bash'ın timeargümanını ayrıştırmadı . Bu ya mevcut olmalı ya da yeni satır olmalıdır. İlk örneğinizde yeni bir satırdır ancak ikincisinde yoktur.

Öte yandan, eğer koşacak olsaydın

ls;date;'time'

veya

ls;'time';date

burada tırnak işaretleri 'time'ayrılmış bir sözcük olarak durumunu iptal eder, o zaman bash satır ayrıştırmada hiçbir sorun yoktur. Şimdi bir listede üç komutu ayrıştırır, bu sırayla yürütür ve /usr/bin/timeher iki durumda da bir kullanım hatası bildirir.

ek

time ; dateBir hata vermesine rağmen , time ; ; datevermediği görülmüştür . Muhtemel açıklama time ;bash tarafından eşdeğer olarak yorumlanmasıdır time <newline>. İfadesi time ; ; datedaha sonra listesi olarak ayrıştırılır time ;ve date.

Bu, yasal olan time ;ve time ; ;aynı zamanda ikincisi, listeden time ;sonra izin verilen isteğe bağlı noktalı virgül içeren tekli liste olarak ayrıştırılan gözlemle tutarlıdır .

Bu nedenle time ; date, hatayı neden bash: syntax error near unexpected token 'date'verdiğini açıklamanın bir başka yolu time, noktalı virgülün onu ayırmasından tüketmesidir date. Bunu sadece timebash ayrılmış bir sözcük olduğu için yapabilir .


Güzel bir açıklama için teşekkürler! Ama sonra yine bu davranış benim için bir hata gibi görünüyor: timeNULL komutuna izin verilmesi gerekiyor ve noktalı virgül listeleri sınırlaması gerekiyor, bu nedenle IMO timekomutu noktalı virgülün ardından "tüketmemeli". Diğer yerleşik komutlar (bağımsız değişkenler alabilir) bu tür davranışlar göstermez.
düzenleyin

@arrange Komplikasyon, zamanın null bir komuta (her şeyi anlamsızlaştırmış) izin vermemesi, sadece komut yerine yeni bir satıra izin vermesidir . Yani time;dateherhangi bir yorumda gerçekten sözdizimsel olarak yanlıştır. Ancak time ; ve time ; ;daha sonra da yasadışı olurdu. Tartışılan edilebilir timebireyin davranış bir hata yoksa sadece (o belgesiz olduğunu ise içlerinde tutarlı), ancak bir hata raporu kesinlikle yerinde olacaktır. Dosyalamak ister misiniz?
zwets

Ben kaynağa baktım (bash4.2: parse.y: 1205-1221 satırları) ve orada bunu söylüyor time by itself can time a null commandve sonra bunu yapıyor $$ = make_simple_command (x, (COMMAND *)NULL);. Bir hata dosyalamak için emin değilim 8)
düzenlemek

Bu sorunun bash-özgü olduğuna dikkat edilmelidir. Yapma time ; dateiçinde çalışmalarını ksh93ve mkshhatta olsa, hatasız ksh var timeanahtar kelime.
Sergiy Kolodyazhnyy

2

Bash time, komut satırlarını ayrıştırırken yerleşik olanı özel bir durum olarak ele alır .

Bash man sayfasında okunabileceği gibi, yazılan satır önce bir listeye ayrılır:

pipeline ; pipeline

burada bir boru hattı:

[time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]

veya bizim durumumuzda, basitçe:

time command

yani zaman varsa, komut da mevcut olmalıdır .

[ timeBir satırsonu gelmesine izin veren özel bir durum var , ancak bu burada geçerli değil]

Yani, bizim durumumuzda, var:

time;date

iki boru hattına ayrılmak:

1. time
2. date

ve boru hattı 1 iyi bir şekilde oluşturulmamıştır, çünkü timekomut olmadan. Dolayısıyla hata.

Komut satırının timeburada da çalışmadığını unutmayın:

$ /usr/bin/time;date
Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]

bash bunu beklendiği gibi 2 boru hattına ayrıştırır:

1. /usr/bin/time
2. date

ve /usr/bin/timesonra hiçbir argüman olmadan çalışmayı reddediyor. Bunun /usr/bin/timebash hatasından kaynaklanan bir hata olduğunu unutmayın .

Arka kene çalışmasının nedeni, arka kene time, boru hattı içinde özel bir eleman olarak yorumlanmasının durmasıdır.

yani arka kene ile:

`time`;date

iki boru hattı olarak ayrıştırılır:

1. `time`
2. date

Bir boru hattının, bizim durumumuzda:

[time] command

ve başlangıçta sorun, timekomut verilmemişti, ki buna izin verilmiyordu. Ama şimdi sadece şu komuta sahibiz:

`time`

öncekiler olmadan, timegeri keneler timeönceki sözcük olarak değil, komut olarak yorumlandığı anlamına gelir .

Bu yüzden bash yapısını timehiçbir argüman olmadan çalıştırır , ki bu kabul edilir. Hiçbir çıktı üretmez ve hata görmüyoruz.

Bunu not et:

`time`

aslında ishal sonucu içinde timeyerleşik, yani ne olursa olsun çalışır timeyerleşik stdout'ta üretir. Ancak timekendi başına stdout'a bir şey yazmadığı için işe yarıyor gibi görünüyor.

Son olarak, bunun işe yaradığı belirtildi:

time ; ; date

ki ne yazık ki açıklayamam :)


Açıklamanızın daha iyi olduğunu düşünüyorum, ama yine de bana garip geliyor. ;dateverir bash: syntax error near unexpected token ;, ama time ;dateverir bash: syntax error near unexpected token date, bu yüzden bash yerleşik zamandan sonra komutu "; tarih" olarak ele almıyor gibi görünüyor. İlginçtir, time ; ; dateçalışır.
düzenlemek

yup, teşekkürler @arrange, oldukça garip. Cevabı biraz güncelleyeceğim.
cdmackay

tamam, @arrange, yeniden yazdım. Yine de sonunu açıklayamıyorum ... iç çekiş.
cdmackay

@cdmackay Geri çivileri ve alıntıları karıştırıyorsunuz. By alıntı 'time' onu rezerve kelime olarak anlamını yitirir. Geri gerdirilmesi , çıkışı komuta eklenmiş bir alt kabukta çalıştırılmasını sağlar. Bunun tartışma ile ilgisi yok. Nitekim olarak, örnek `time\';datetalebinizin tersini kanıtlıyor: Bu gerektiğini çünkü akıl tarafından bir hata vermek /usr/bin/timebir bağımsız değişken gerektirir. Bunun nedeni, yürüttüğü alt kabukta bir timekez daha ayrılmış sözcük olmasıdır .
zwets

@arrange Her ikisi de sözdizimi hatalarıdır ve her ikisinin de aynı yere yakın olduğu bildirilmiştir , bu yüzden orada bir tutarsızlık görmüyorum. Sözdizimi hatası alanına girdiğinde, ayrıştırıcının çıkış yolunu bilmesini bekleyemezsiniz. Bir ayrıştırıcıya gereksinim duyarsanız, sadece yasal sözdizimini değil , tanım gereği imkansız olan her olası yasadışı yapının sözdizimini de bilmelidir .
zwets
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.