Toplu betiklerin gramerini araştırmak için deneyler yaptık. Ayrıca, toplu iş ve komut satırı modu arasındaki farkları araştırdık.
Toplu Satır Ayrıştırıcı:
Toplu iş dosyası satır ayrıştırıcısındaki aşamalara kısa bir genel bakış:
Aşama 0) Okuma Satırı:
Aşama 1) Yüzde Genişleme:
Aşama 2) Özel karakterleri işleyin, önbelleğe alınmış bir komut bloğu belirtin ve oluşturun: Bu, tırnak işaretleri, özel karakterler, belirteç sınırlayıcılar ve düzeltme işareti kaçışları gibi şeylerden etkilenen karmaşık bir işlemdir.
Aşama 3) Ayrıştırılan komutları yankılama Yalnızca komut bloğu başlamamışsa @
ve önceki adımın başında ECHO AÇIK ise.
Aşama 4) FOR %X
değişken genişletme: Sadece bir FOR komutu aktifse ve DO'dan sonraki komutlar işleniyorsa.
Aşama 5) Gecikmeli Genişleme: Yalnızca gecikmeli genişleme etkinse
Aşama 5.3) Boru işleme: Yalnızca komutlar bir borunun her iki tarafındaysa
Aşama 5.5) Yeniden Yönlendirme Yürütme:
Aşama 6) ÇAĞRI işleme / Düzeltme çiftleme: Yalnızca komut belirteci ÇAĞRI ise
Aşama 7) Yürüt: Komut yürütülür
Her aşama için detaylar:
Aşağıda açıklanan aşamaların yalnızca toplu ayrıştırıcının nasıl çalıştığının bir modeli olduğunu unutmayın. Gerçek cmd.exe iç bileşenleri bu aşamaları yansıtmayabilir. Ancak bu model, toplu komut dosyalarının davranışını tahmin etmede etkilidir.
Aşama 0) Okuma Satırı: İlk önce giriş satırını okuyun <LF>
.
- Komut olarak ayrıştırılacak satırı okurken,
<Ctrl-Z>
(0x1A) <LF>
(LineFeed 0x0A) olarak okunur
- Bir için tararken GOTO veya ÇAĞRI hatları okuduğunda: etiket,
<Ctrl-Z>
kendisi olarak kabul edilir - bu bir değil dönüştürüldü<LF>
Aşama 1) Yüzde Genişleme:
- Bir çiftin
%%
yerine tek bir%
- Bağımsız değişken genişlemesi (
%*
, %1
, %2
vs.)
- Genişlemesi,
%var%
var yoksa hiçbir şeyle değiştirmeyin
- Çizgi ilk başta genişleme
<LF>
dahilinde kesilir%var%
- Tam bir açıklama için bunun ilk yarısını dbenham'dan okuyun Aynı konu: Yüzde Faz
Aşama 2) Özel karakterleri işleyin, önbelleğe alınmış bir komut bloğu belirtin ve oluşturun: Bu, tırnak işaretleri, özel karakterler, belirteç sınırlayıcılar ve düzeltme işareti kaçışları gibi şeylerden etkilenen karmaşık bir işlemdir. Aşağıda, bu sürecin bir yaklaşımı yer almaktadır.
Bu aşamada önemli olan kavramlar vardır.
- Bir belirteç, birim olarak kabul edilen bir karakter dizisidir.
- Jetonlar belirteç sınırlayıcılarla ayrılır. Standart belirteç sınırlayıcılar
<space>
<tab>
;
,
=
<0x0B>
<0x0C>
ve <0xFF>
Ardışık belirteç sınırlayıcılar tek olarak ele alınır - belirteç sınırlayıcılar arasında boş belirteç yoktur
- Alıntılanan bir dizede belirteç sınırlayıcı yok. Alıntılanan dizenin tamamı her zaman tek bir simgenin parçası olarak ele alınır. Tek bir belirteç, tırnak içine alınmış dizelerin ve tırnaksız karakterlerin birleşiminden oluşabilir.
Aşağıdaki karakterler, bağlama bağlı olarak bu aşamada özel bir anlama sahip olabilir: <CR>
^
(
@
&
|
<
>
<LF>
<space>
<tab>
;
,
=
<0x0B>
<0x0C>
<0xFF>
Her karaktere soldan sağa bakın:
- Daha
<CR>
sonra, hiç orada değilmiş gibi kaldırın (garip yönlendirme davranışı hariç )
- Bir düzeltme (
^
) ise, bir sonraki karakter kaçar ve çıkış yapan düzeltme işareti kaldırılır. Kaçan karakterler tüm özel anlamları kaybeder (hariç <LF>
).
- Bir teklif (
"
) ise, teklif bayrağını değiştirin. Teklif bayrağı etkinse, yalnızca o zaman "
ve <LF>
özeldir. Diğer tüm karakterler, bir sonraki tırnak tırnak işaretini kaldırana kadar özel anlamlarını yitirir. Kapanış teklifinden kaçmak mümkün değildir. Alıntılanan tüm karakterler her zaman aynı jeton içindedir.
<LF>
her zaman teklif bayrağını kapatır. Diğer davranışlar bağlama göre değişir, ancak tırnak işaretleri hiçbir zaman davranışını değiştirmez <LF>
.
- Kaçtı
<LF>
<LF>
soyulmuş
- Bir sonraki karakter kaçar. Satır tamponunun sonunda, bir sonraki satır 1 ve 1.5 fazları tarafından okunur ve işlenir ve bir sonraki karakterden kaçmadan önce geçerli olana eklenir. Bir sonraki karakter ise
<LF>
, o zaman bir değişmez olarak kabul edilir, yani bu süreç özyinelemeli değildir.
- Çıkışsız
<LF>
parantez içinde değil
<LF>
çıkarılır ve geçerli satırın ayrıştırılması sonlandırılır.
- Satır arabelleğinde kalan karakterler yok sayılır.
<LF>
FOR IN parantez içindeki bloktan
kaçtı
<LF>
dönüştürülür <space>
- Satır ara belleğinin sonunda bir sonraki satır okunur ve geçerli satırın sonuna eklenir.
<LF>
Parantez içine alınmış komut bloğunda
kaçış yok
<LF>
dönüştürülür <LF><space>
ve <space>
komut bloğunun bir sonraki çizgi parçası olarak kabul edilir.
- Satır ara belleğinin sonundaysa, sonraki satır okunur ve boşluğa eklenir.
- Özel karakterlerden biri
&
|
<
veya >
, boruları, komut birleştirme ve yeniden yönlendirme işlemek için bu noktada satırı bölün.
- Bir boru (
|
) söz konusu olduğunda , her iki taraf da 5.3.
- Halinde
&
, &&
ya da ||
bir komut birleştirme, birleştirme her iki tarafı ayrı komut olarak işlenir.
- Durumunda
<
, <<
, >
ya da >>
yönlendirme, yönlendirme maddesi geçici olarak çıkarılmış, ayrıştırılır, ve daha sonra mevcut komutun sonuna eklenen. Yeniden yönlendirme yan tümcesi, isteğe bağlı bir dosya tanıtıcı basamağı, yeniden yönlendirme işleci ve yeniden yönlendirme hedef belirtecinden oluşur.
- Yeniden yönlendirme işlecinden önce gelen belirteç, tek bir çıkış karakteri olmayan tek basamaksa, basamak yeniden yönlendirilecek dosya tanıtıcısını belirtir. Tanıtıcı belirteci bulunmazsa, çıkış yeniden yönlendirme varsayılanı 1 (stdout) ve giriş yeniden yönlendirme varsayılanı 0 (stdin) olur.
- İlk (önceki ucuna yeniden yönlendirme hareketli kadar) bu komut için belirteci Eğer başlar
@
, sonra @
özel bir anlamı vardır. ( @
başka bir bağlamda özel değildir)
- Özel
@
kaldırıldı.
- ECHO AÇIK ise, bu komut, bu satırda aşağıdaki sıralı komutlarla birlikte, 3. aşama yankısının dışında tutulur. Bir
@
açıklıktan önce ise (
, parantez içindeki tüm blok faz 3 ekodan hariç tutulur.
- İşlem parantezi (birden çok satırda bileşik ifadeler sağlar):
- Ayrıştırıcı bir komut belirteci
(
aramıyorsa, özel değildir.
- Ayrıştırıcı bir komut belirteci arıyor ve bulursa
(
, yeni bir bileşik deyimi başlatın ve parantez sayacını artırın
- Parantez sayacı> 0 ise
)
, bileşik ifadesini sonlandırır ve parantez sayacını azaltır.
- Satır ucuna ulaşılırsa ve parantez sayacı> 0 ise, bir sonraki satır bileşik ifadesine eklenir (yeniden faz 0 ile başlar)
- Parantez sayacı 0 ise ve ayrıştırıcı bir komut arıyorsa , hemen bir belirteç sınırlayıcı, özel karakter, yeni satır veya dosya sonu geldiği sürece
)
bir REM
ifadeye
benzer şekilde çalışır
- Dışındaki tüm özel karakterler anlamlarını yitirir
^
(satır birleştirme mümkündür)
- Mantıksal satırın sonuna ulaşıldığında, tüm "komut" atılır.
- Her komut bir dizi jetona ayrıştırılır. İlk belirteç her zaman bir komut belirteci olarak kabul edilir (özel öğütme yapıldıktan
@
ve yeniden yönlendirme sona erdikten sonra).
- Komut belirtecinden önce önde gelen belirteç sınırlayıcılar çıkarılır
- Komut belirtecini ayrıştırırken
(
, standart belirteç sınırlayıcılarına ek olarak bir komut belirteci sınırlayıcısı olarak işlev görür
- Sonraki tokenlerin kullanımı komuta bağlıdır.
- Çoğu komut, komut belirtecinden sonraki tüm bağımsız değişkenleri tek bir bağımsız değişken belirtecinde birleştirir. Tüm argüman belirteci sınırlayıcıları korunur. Bağımsız değişken seçenekleri genellikle faz 7'ye kadar ayrıştırılmaz.
- Üç komut özel işlem görür - IF, FOR ve REM
- IF, bağımsız olarak işlenen iki veya üç ayrı parçaya bölünür. IF yapısındaki bir sözdizimi hatası, önemli bir sözdizimi hatasına neden olacaktır.
- Karşılaştırma işlemi, aşama 7'ye kadar akan gerçek komuttur
- Tüm IF seçenekleri aşama 2'de tamamen ayrıştırılır.
- Ardışık jeton sınırlayıcıları tek bir boşluğa dalar.
- Karşılaştırma operatörüne bağlı olarak, tanımlanan bir veya iki değer belirteci olacaktır.
- True komut bloğu, koşuldan sonraki komut kümesidir ve diğer komut blokları gibi ayrıştırılır. ELSE kullanılacaksa, True bloğunun parantez içinde olması gerekir.
- İsteğe bağlı Yanlış komut bloğu, ELSE'ten sonraki komut kümesidir. Yine, bu komut bloğu normal şekilde ayrıştırılır.
- Doğru ve Yanlış komut blokları sonraki aşamalara otomatik olarak akmaz. Takip eden işlemleri faz 7 ile kontrol edilir.
- FOR, DO'dan sonra ikiye bölünür. FOR yapısında bir sözdizimi hatası, önemli bir sözdizimi hatasına neden olacaktır.
- DO'dan geçen kısım, faz 7'ye kadar akan gerçek FOR yineleme komutudur
- Tüm FOR seçenekleri aşama 2'de tamamen ayrıştırılır.
- IN yan tümcesi davranır parantez
<LF>
olarak <space>
. IN deyimi ayrıştırıldıktan sonra, tüm belirteçler tek bir belirteç oluşturmak için bir araya getirilir.
- Ardışık çıkışsız / sıralanmamış simge sınırlayıcıları, DO aracılığıyla FOR komutu boyunca tek bir boşluğa daraltır.
- DO'dan sonraki bölüm, normal olarak ayrıştırılan bir komut bloğudur. Daha sonra DO komut bloğunun işlenmesi, faz 7'deki yineleme ile kontrol edilir.
- Faz 2'de tespit edilen REM, diğer tüm komutlardan önemli ölçüde farklı muamele görür.
- Yalnızca bir bağımsız değişken belirteci ayrıştırılır - ayrıştırıcı, ilk bağımsız değişken belirtecinden sonraki karakterleri yok sayar.
- REM komutu, faz 3 çıkışında görünebilir, ancak komut hiçbir zaman yürütülmez ve orijinal bağımsız değişken metni yankılanır - kaçan satırlar kaldırılmaz, ancak ...
^
Satırı sona erdiren çıkış karakterini biten tek bir argüman belirteci varsa, argüman belirteci atılır ve sonraki satır ayrıştırılır ve REM'e eklenir. Birden fazla belirteç olana veya son karakter bulunmayana kadar bu tekrarlanır ^
.
- Komut belirteci ile başlıyorsa
:
ve bu, 2. aşamanın ilk turuysa (6. aşamadaki CALL nedeniyle yeniden başlatma değil)
- Jeton normalde Beklenmedik Etiket olarak işlem görür .
- Hattının geri kalan, ancak, ayrıştırılır
)
, <
, >
, &
ve |
artık özel bir anlama sahiptir. Satırın geri kalanının tamamı "komut" etiketinin bir parçası olarak kabul edilir.
- Özel
^
olmaya devam eder, yani satır devam etmesi etikete sonraki satırı eklemek için kullanılabilir.
- Bir İcra Edilmemiş Etiket hemen bir komutun izlediği veya sürece bir parantez blok içinde ölümcül bir sözdizimi hata ile sonuçlanır Etiket Gerçekleştirilen sonraki satırda.
(
artık Denetlenmeyen Etiketi izleyen ilk komut için özel bir anlamı yoktur .
- Etiket ayrıştırma işlemi tamamlandıktan sonra komut iptal edilir. Etiket için sonraki aşamalar gerçekleşmez
- Aşama 2'de bulunan bir etiketin , Aşama 7 boyunca ayrıştırmaya devam eden bir Yürütülmüş Etiket olarak ele alınmasına neden olabilecek üç istisna vardır .
- İlerlettiği etiket belirteci olduğunu yönlendirme yoktur ve orada
|
boru veya &
, &&
ya da ||
on line komut birleştirme.
- Etiket belirtecinden önce gelen yönlendirme vardır ve komut parantez içinde bir blok içerisindedir.
- Etiket belirteci, parantez içindeki bir satırdaki bir satırdaki ilk komuttur ve yukarıdaki satır Beklenmedik Etiket ile sona erdi .
- Faz 2'de bir Yürütülmüş Etiket bulunduğunda
aşağıdakiler gerçekleşir
- Etiket, argümanları ve yönlendirmesi, 3. aşamadaki herhangi bir yankı çıktısının dışında bırakılır
- Satırdaki sonraki birleştirilmiş komutlar tamamen ayrıştırılır ve yürütülür.
- Yürütülen Etiketler ve Beklenmeyen Etiketler hakkında daha fazla bilgi için bkz. Https://www.dostips.com/forum/viewtopic.php?f=3&t=3803&p=55405#p55405
Aşama 3) Ayrıştırılan komutları yankılama Yalnızca komut bloğu başlamamışsa @
ve önceki adımın başında ECHO AÇIK ise.
Aşama 4) FOR %X
değişken genişletme: Sadece bir FOR komutu aktifse ve DO'dan sonraki komutlar işleniyorsa.
- Bu noktada, toplu işlemin 1. aşaması zaten bir FOR değişkenini benzer hale
%%X
getirmiş olacaktır %X
. Komut satırı, 1. aşama için farklı yüzde genişletme kurallarına sahiptir. Bu, komut satırlarının kullanması, %X
ancak toplu iş dosyaları %%X
FOR değişkenleri için kullanmasının nedenidir .
- FOR değişken adları büyük / küçük harfe duyarlıdır, ancak
~modifiers
büyük / küçük harfe duyarlı değildir.
~modifiers
Değişken isimlerine göre öncelik kazanır. Aşağıdaki karakter ~
hem bir değiştirici hem de geçerli bir FOR değişkeni adı ise ve etkin bir FOR değişkeni adı olan bir sonraki karakter varsa, karakter değiştirici olarak yorumlanır.
- FOR değişken adları geneldir, ancak yalnızca bir DO cümlesi bağlamındadır. Bir yordam bir FOR DO yantümcesinden çağırılırsa, FOR değişkenleri ARANAN yordamın içinde genişletilmez. Ancak rutinin kendi FOR komutu varsa, o anda tanımlanmış olan tüm FOR değişkenlerine iç DO komutları tarafından erişilebilir.
- FOR değişken adları iç içe FORs içinde yeniden kullanılabilir. İç FOR değeri öncelik taşır, ancak INNER FOR kapatıldıktan sonra dış FOR değeri geri yüklenir.
- ECHO bu aşamanın başlangıcında AÇIK ise, FOR 3 değişkenleri genişletildikten sonra ayrıştırılmış DO komutlarını göstermek için faz 3) tekrarlanır.
---- Bu noktadan itibaren, 2. aşamada tanımlanan her komut ayrı ayrı işlenir.
---- Bir komut için diğerine geçmeden önce 5 ila 7 arasındaki aşamalar tamamlanır.
Aşama 5) Gecikmeli Genişleme: Yalnızca gecikmeli genişleme açıksa, komut bir borunun her iki tarafındaki parantez içinde yer almaz ve komut "açık" bir toplu komut dosyası değildir (parantez olmadan komut dosyası adı, CALL, komut birleştirme, veya boru).
- Bir komutun her belirteci, gecikmeli genişletme için bağımsız olarak ayrıştırılır.
- Çoğu komut iki veya daha fazla jetonu ayrıştırır - komut jetonu, bağımsız değişken jetonu ve her yeniden yönlendirme hedef jetonu.
- FOR komutu yalnızca IN yan tümcesi belirtecini ayrıştırır.
- IF komutu karşılaştırma değerlerini yalnızca karşılaştırır - karşılaştırma işlecine bağlı olarak bir veya iki.
- Ayrıştırılan her jeton için öncelikle içerdiği herhangi bir simge olup olmadığını kontrol edin
!
. Değilse, kod ayrıştırılmaz - ^
karakterler için önemlidir . Jeton içeriyorsa !
, her karakteri soldan sağa tarayın:
- Eğer bir düzeltme işareti (
^
) ise, bir sonraki karakterin özel bir anlamı yoktur, düzeltme işaretinin kendisi kaldırılır
- Bir ünlem işareti ise, bir sonraki ünlem işaretini arayın (artık düzeltme işaretleri görülmez), değişkenin değerine genişletin.
- Art arda açılan
!
tek bir parça halinde!
- Eşleştirilmemiş kalanlar
!
kaldırıldı
- Bu aşamada genişleyen değişkenler "güvenli" dir, çünkü artık özel karakterler algılanmaz (hatta
<CR>
veya <LF>
)
- Daha eksiksiz bir açıklama için, dbenham aynı iplikten bunun 2. yarısını okuyun
- Exclamation Point Phase
Aşama 5.3) Boru işleme: Yalnızca komutlar bir borunun
her iki tarafındaysa Borunun her iki tarafı bağımsız ve asenkron olarak işlenir.
- Komut cmd.exe dosyasının içindeyse veya bir toplu iş dosyasıysa veya parantez içine alınmış bir komut bloğuysa, yeni bir cmd.exe iş parçacığında yürütülür
%comspec% /S /D /c" commandBlock"
, bu nedenle komut bloğu bir faz yeniden başlatma alır, ancak bu sefer komut satırı modunda.
- Parantez içine alınmış bir komut bloğu varsa,
<LF>
önce ve sonra bir komuta sahip olanların tümü dönüştürülür <space>&
. Diğerleri <LF>
soyulur.
- Bu, boru komutları için işlemenin sonu.
- Bkz zaman bir kod borulu bloğunun içinde Neden gecikmeli genişleme başarısız oluyor? boru ayrıştırma ve işleme hakkında daha fazla bilgi için
Aşama 5.5) Yeniden Yönlendirme Yürüt: 2. aşamada bulunan herhangi bir yeniden yönlendirme şimdi yürütülür.
Aşama 6) CALL işleme / Caret ikiye katlama: Yalnızca komut belirteci CALL ise veya ilk oluşan standart belirteç sınırlayıcıdan önceki metin CALL ise. CALL daha büyük bir komut belirtecinden ayrıştırılırsa, kullanılmayan kısım devam etmeden önce bağımsız değişken belirtecine eklenir.
- Bağımsız değişken belirtecini tırnaksız olarak tarayın
/?
. Jetonlar içinde herhangi bir yerde bulunursa, 6. aşamayı iptal edin ve ÇAĞRI YARDIMININ yazdırılacağı Faz 7'ye geçin.
- İlkini kaldırın
CALL
, böylece birden fazla ÇAĞRI istiflenebilir
- Tüm taşıyıcıları ikiye katla
- Faz 1, 1.5 ve 2'yi yeniden başlatın, ancak faz 3'e devam etmeyin
- İki katına çıkarılan caretler, alıntılanmadığı sürece bir araca geri indirilir. Ancak maalesef alıntı yapılan caretler iki katına çıkar.
- Faz 1 biraz değişiyor
- Adım 1.2 veya 1.3'teki genişletme hataları CALL'u iptal eder, ancak hata ölümcül değildir - toplu işleme devam eder.
- Faz 2 görevleri biraz değiştirildi
- Aşama 2'nin ilk turunda algılanmayan yeni görünen tırnaksız, çıkışsız yeniden yönlendirme algılanır, ancak yeniden yönlendirme gerçekleştirilmeden kaldırılır (dosya adı dahil)
- Hattın sonunda yeni görünen alıntılanmamış, boş bırakılmayan çizgi, çizgi devam etmeden kaldırılır
- Aşağıdakilerden herhangi biri algılanırsa ÇAĞRI hatasız iptal edilir
- Yeni görünen alıntılanmamış, boş bırakılmayan
&
veya|
- Ortaya çıkan komut belirteci alıntılanmamış, çıkışsız ile başlar
(
- Kaldırılan CALL'ın başlamasından sonraki ilk belirteç
@
- Ortaya çıkan komut, görünüşte geçerli bir IF veya FOR ise, yürütme daha sonra bunu belirten
IF
veya FOR
dahili veya harici komut olarak tanınmayan bir hata ile başarısız olur .
- Sonuçta elde edilen komut belirteci ile başlayan bir etiketse, elbette CALL, 2. fazın bu 2. turunda iptal edilmez
:
.
- Ortaya çıkan komut belirteci CALL ise, 6. Aşamayı yeniden başlatın (CALL kalmayana kadar tekrar eder)
- Ortaya çıkan komut belirteci bir toplu iş komut dosyası veya: etiketiyse, ÇAĞRI'nın yürütülmesi, Aşama 6'nın geri kalanı tarafından tamamen işlenir.
- ÇAĞRI tamamlandığında yürütmenin doğru konumdan devam edebilmesi için, çağrı yığınındaki geçerli toplu komut dosyası konumunu itin.
- Tüm sonuç jetonlarını kullanarak CALL için% 0,% 1,% 2, ...% N ve% * bağımsız değişken belirteçlerini ayarlayın
- Komut belirteci ile başlayan bir etiketse
:
,
- Aşama 5'i yeniden başlatın. Bu, aşağıdakileri etkileyebilir: etiketin ARANMASI. Ancak% 0 vb. Belirteçleri önceden ayarlandığından, ÇAĞRI yordamına iletilen bağımsız değişkenleri değiştirmez.
- Dosya işaretçisini altyordamın başlangıcına konumlandırmak için GOTO etiketini yürütün (aşağıdakileri izleyebilecek diğer simgeleri yoksayın) GOTO'nun nasıl çalıştığına ilişkin kurallar için Aşama 7'ye bakın.
- : Label jetonu eksikse veya: label bulunamazsa, kaydedilen dosya konumunu geri yüklemek için çağrı yığını derhal açılır ve CALL iptal edilir.
- : Etiketi /? İçeriyorsa,: etiketi aramak yerine GOTO yardımı yazdırılır. Dosya işaretçisi hareket etmiyor, öyle ki CALL'dan sonraki kod iki kez, bir kez CALL bağlamında ve sonra tekrar CALL dönüşünden sonra yürütülüyor. Bkz Neden ÇAĞRI bu senaryodaki GOTO Yardım iletisi? Ve neden komut bundan sonra iki kez yürütülür? daha fazla bilgi için.
- Belirtilen toplu iş komut dosyasına başka aktarım denetimi.
- CALLed: etiketinin veya komut dosyasının yürütülmesi EXIT / B veya dosya sonuna erişilene kadar devam eder; bu noktada CALL yığını açılır ve yürütme kaydedilen dosya konumundan devam eder.
ARAMA komut dosyaları veya: etiketleri için Aşama 7 yürütülmez.
- Aksi takdirde, faz 6'nın sonucu yürütme için faz 7'ye düşer.
Aşama 7) Yürüt: Komut yürütülür
- 7.1 - Dahili komutu yürüt - Komut jetonu belirtilmişse, bu adımı atlayın. Aksi takdirde, dahili bir komutu çözümlemeye ve yürütmeye çalışın.
- Alıntılanmamış bir komut belirtecinin bir iç komutu temsil edip etmediğini belirlemek için aşağıdaki testler yapılır:
- Komut belirteci dahili bir komutla tam olarak eşleşiyorsa, yürütün.
- Komut belirtecinin ilk oluşumundan önce kırılması
+
/
[
]
<space>
<tab>
,
;
veya =
Önceki metin dahili bir komutsa, o komutu hatırlayın
- Komut satırı modundaysa veya komut parantez içine alınmış bir bloksa, IF doğru veya yanlış komut bloğu, FOR DO komut bloğu ise veya komut birleştirme işlemiyle ilgiliyse, dahili komutu yürütün
- Başka (toplu modda tek başına bir komut olmalıdır) geçerli klasörü ve PATH'yi, taban adı orijinal komut belirteciyle eşleşen bir .COM, .EXE, .BAT veya .CMD dosyası için tarayın
- İlk eşleşen dosya bir .BAT veya .CMD ise, 7.3.exec dosyasına gidin ve bu komut dosyasını yürütün
- Başka (eşleşme bulunamadı veya ilk eşleşme .EXE veya .COM) hatırlanan dahili komutu yürütün
- Else komut belirtecini ilk oluşumundan önce kırma
.
\
veya :
Önceki metin dahili bir komut değilse, 7.2'ye git
Önceki metin başka bir dahili komut olabilir. Bu komutu hatırla.
- Komut belirtecini ilk oluşumundan önce kırma
+
/
[
]
<space>
<tab>
,
;
veya =
Önceki metin varolan bir dosyaya giden yolsa, 7,2
Diğerse hatırlanan dahili komutu yürütür.
- Bir iç komut daha büyük bir komut belirtecinden ayrıştırılırsa, komut belirtecinin kullanılmayan kısmı bağımsız değişken listesine eklenir
- Bir komut belirtecinin dahili bir komut olarak ayrıştırılması, başarılı bir şekilde yürütülmesi anlamına gelmez. Her dahili komutun, bağımsız değişkenlerin ve seçeneklerin nasıl ayrıştırıldığı ve hangi sözdizimine izin verildiğiyle ilgili kendi kuralları vardır.
- Tüm dahili komutlar
/?
algılanırsa işlevlerini yerine yardım yazdırır . Çoğu /?
, argümanlarda herhangi bir yerde göründüğünü tanır . Ancak ECHO ve SET gibi birkaç komut yalnızca ilk argüman belirteci ile başlarsa yardımı yazdırır /?
.
- SET'in bazı ilginç semantiği vardır:
- SET komutunun değişken adı ve uzantıları etkinleştirilmeden önce bir alıntısı varsa
set "name=content" ignored
-> değer = content
o zaman ilk eşittir işareti ile son tırnak arasındaki metin içerik olarak kullanılır (ilk eşit ve son tırnak hariç). Son alıntıdan sonraki metin yoksayılır. Eşittir işaretinden sonra bir alıntı yoksa, satırın geri kalanı içerik olarak kullanılır.
- SET komutunun
set name="content" not ignored
-> value = adından önce bir alıntı yoksa "content" not ignored
, eşitten sonraki satırın geri kalanının tamamı, mevcut olabilecek tüm tırnak işaretleri de dahil olmak üzere içerik olarak kullanılır.
- Bir IF karşılaştırması değerlendirilir ve koşulun doğru veya yanlış olmasına bağlı olarak, 5. aşamadan başlayarak uygun olarak ayrıştırılmış bağımlı komut bloğu işlenir.
- FOR komutunun IN yan tümcesi uygun şekilde yinelenir.
- Bu bir komut bloğunun çıkışını yineleyen bir FOR / F ise, o zaman:
- IN yan tümcesi CMD / C aracılığıyla yeni bir cmd.exe işleminde yürütülür.
- Komut bloğu tüm ayrıştırma işleminden ikinci kez geçmelidir, ancak bu sefer bir komut satırı bağlamında
- ECHO başlayacak ve gecikmeli genişletme genellikle devre dışı bırakılacaktır (kayıt defteri ayarına bağlı olarak)
- Alt cmd.exe işlemi sona erdiğinde IN yan tümcesi komut bloğu tarafından yapılan tüm ortam değişiklikleri kaybolur
- Her yineleme için:
- FOR değişken değerleri tanımlanır
- Daha önce ayrıştırılmış DO komut bloğu daha sonra 4. aşamadan başlayarak işlenir.
- GOTO, etiketi bulmak için aşağıdaki mantığı kullanır:
- Etiket ilk bağımsız değişken belirtecinden ayrıştırılır
- Komut dosyası, etiketin bir sonraki tekrarlaması için taranır
- Tarama geçerli dosya konumundan başlar
- Dosyanın sonuna erişilirse, tarama dosyanın başına geri döner ve orijinal başlangıç noktasına devam eder.
- Tarama, bulduğu etiketin ilk gerçekleşmesinde durur ve dosya işaretçisi, etiketi hemen takip eden satıra ayarlanır. Komut dosyasının yürütülmesi bu noktadan itibaren devam eder. Başarılı bir gerçek GOTO'nun, FOR döngüleri de dahil olmak üzere ayrıştırılmış kod bloğunu derhal iptal edeceğini unutmayın.
- Etiket bulunamazsa veya etiket belirteci eksikse, GOTO başarısız olur, bir hata mesajı yazdırılır ve çağrı yığını açılır. Bu, etkili bir şekilde EXIT / B olarak işlev görür, ancak geçerli komut bloğunda GOTO'yu izleyen ayrıştırılmış komutlar hala yürütülür, ancak CALLer bağlamında (EXIT / B'den sonra var olan bağlam)
- Etiketleri ayrıştırmak için kullanılan kuralların daha kesin bir açıklaması için bkz. Https://www.dostips.com/forum/viewtopic.php?f=3&t=3803 .
- RENAME ve COPY, kaynak ve hedef yollar için joker karakter kabul eder. Ancak Microsoft, özellikle hedef yol için joker karakterlerin nasıl çalıştığını belgeleyen korkunç bir iş çıkarır. Windows RENAME komutu joker karakterleri nasıl yorumluyor? Bölümünde yararlı bir joker karakter kuralları dizisi bulunabilir.
- 7.2 - Ses düzeyi değiştirme yürütme - Komut belirteci bir alıntı ile başlamazsa, tam olarak iki karakter uzunluğunda ve 2. karakter iki nokta üst üste ise, ses düzeyini değiştirin
- Tüm argüman simgeleri yok sayılır
- İlk karakter tarafından belirtilen birim bulunamazsa, hatayla iptal edin
- İçin
::
bir birim tanımlamak için SUBST kullanılmadığı sürece, komut jetonu her zaman hataya neden olur. Bir birim tanımlamak için ::
SUBST kullanılırsa ::
, birim değiştirilir, etiket olarak değerlendirilmez.
- 7.3 - Harici komut yürütme - Aksi takdirde komutu harici bir komut olarak ele almaya çalışın.
- Komut satırı modu ve komut işlem görmeyen ve bir hacim özellikleri, beyaz boşluk ile başlamıyorsa,
,
, ;
, =
ya da +
daha sonra ilk durumda belirteci komutu kırmak <space>
,
;
ya da =
ve (ler) belirteci argüman kalan çizgi yerleştirirler.
- Komut simgesinin 2. karakteri iki nokta üst üste ise, 1. karakter tarafından belirtilen ses düzeyinin bulunabildiğini doğrulayın.
Birim bulunamıyorsa, hatayla iptal edin.
- Toplu modda ve komut belirteci ile
başlarsa,
:
git 7.4 7.4
Etiket belirteci ile başlarsa, ::
bir birim tanımlamak için SUBST kullanılmadıkça önceki adımda bir hata ile iptal edileceğinden buna ulaşılamayacağını unutmayın ::
.
- Yürütülecek harici komutu tanımlayın.
- Bu, geçerli birim, geçerli dizin, PATH değişkeni, PATHEXT değişkeni ve veya dosya ilişkilendirmelerini içerebilen karmaşık bir işlemdir.
- Geçerli bir harici komut tanımlanamazsa, hatayla iptal edin.
- Komut satırı modunda ve komut belirteci ile başlıyorsa
:
, 7.4'e gidin
. Komut belirteci ile başlamadığı ::
ve SUBST için bir birim tanımlanmadığı sürece bir önceki adımda bir hata ile iptal edildiğinden ::
ve tüm komut simgesi harici bir komut için geçerli bir yoldur.
- 7.3.exec - Harici komutu yürütün.
- 7.4 - Etiketi yoksay - Komut simgesi ile başlarsa komutu ve tüm bağımsız değişkenlerini yok sayın
:
.
7.2 ve 7.3'deki kurallar bir etiketin bu noktaya ulaşmasını engelleyebilir.
Komut Satırı Ayrıştırıcı:
BatchLine-Parser gibi çalışır, ancak:
Aşama 1) Yüzde Genişleme:
- Hayır
%*
, %1
vb. Argüman genişletme
- Var tanımsızsa,
%var%
değişmeden kalır.
- Özel işlem yok
%%
. Var = content ise, %%var%%
değerine genişler %content%
.
Aşama 3) Ayrıştırılan komutları yankılayın
- Bu, 2. aşamadan sonra gerçekleştirilmez. Sadece FOR DO komut bloğu için 4. aşamadan sonra gerçekleştirilir.
Aşama 5) Gecikmeli Genişleme: yalnızca Gecikmeli Genişletme etkinse
- Var tanımsızsa,
!var!
değişmeden kalır.
Aşama 7) Komutu Yürüt
- CALL veya GOTO a: label girişimleri hatayla sonuçlanır.
- Faz 7'de zaten belgelendiği gibi, yürütülen bir etiket farklı senaryolarda hataya neden olabilir.
- Toplu olarak yürütülen etiketler, yalnızca şununla başlarlarsa hataya neden olabilir:
::
- Komut satırı yürütülen etiketler neredeyse her zaman hataya neden olur
Tamsayı değerlerinin ayrıştırılması
Cmd.exe dosyasının dizelerden tamsayı değerlerini ayrıştırdığı ve kuralların tutarsız olduğu birçok farklı bağlam vardır:
SET /A
IF
%var:~n,m%
(değişken alt dize genişletme)
FOR /F "TOKENS=n"
FOR /F "SKIP=n"
FOR /L %%A in (n1 n2 n3)
EXIT [/B] n
Bu kuralların ayrıntıları CMD.EXE'nin sayıları ayrıştırma kurallarında bulunabilir
Cmd.exe ayrıştırma kurallarını geliştirmek isteyen herkes için, DosTips forumunda sorunların bildirilebileceği ve önerilerin sunulduğu bir tartışma konusu vardır .
Umarım
Jan Erik (jeb) yardımcı olur - Orijinal yazar ve aşamaların keşfedicisi
Dave Benham (dbenham) - Çok fazla içerik ve düzenleme