Materiał znaleziony gdzieś w internecie

Pliki wsadowe systemu MS-DOS

1. Budowa pliku wsadowego

2. Polecenie ECHO

3. Instrukcja warunkowa (1)

4. Etykiety i instrukcja skoku GOTO

5. Argumenty plików wsadowych

6. Instrukcja warunkowa (2)

7. Instrukcja CALL

8. Instrukcja warunkowa (3)

9. Instrukcja iteracyjna FOR

Budowa pliku wsadowego

Plik wsadowy (ang. batch file) umoŜliwia wykonanie dowolnego ciągu poleceń systemu MS-DOS.

Z punktu widzenia systemu operacyjnego plikiem wsadowym jest kaŜdy plik, którego nazwa

posiada rozszerzenie bat.

Po wydaniu dowolnego polecenia interpreter command.com sprawdza w pierwszej kolejności czy

wydana komenda jest poleceniem wewnętrznym (interpretowanym przez command.com) i w

przypadku odpowiedzi pozytywnej wykonuje wydaną komendę. JeŜeli jednak interpreter nie

rozpoznaje polecenia to przyjmuje, Ŝe uŜytkownik zarządał uruchomienia programu.

Dla przykładu przyjmijmy, Ŝe wpisano komendę

sleep 10

Command.com poszukuje wówczas pliku o nazwie o nazwie sleep.com, następnie pliku sleep.exe i

ostecznie pliku sleep.bat. Po znalezieniu jednego z dwóch pierwszych zbiorów command.com

uruchamia znaleziony program, w przypadku znalezienia zbioru bat wykonuje jego interpretację.

Plik wsadowy, aby mógł być poprawnie wykonany (zinterpretowany) powinien zawierać ciąg

poleceń systemu, z których kaŜde powinno być umieszczone w osobnej linii pliku. Mogą to być polecenia wewnetrzne, polecenia zewnętrzne (programy) lub polecenia specyficzne dla pliku

wsadowego

(polecenia,

które

są

dozwolone

tylko

w

tym

pliku).

Oto prosty przykład pliku wsadowego:

REM Plik Info.bat

ECHO Konfiguracja systemu MS-DOS

ECHO [autoexec.bat]

TYPE C:\autoexec.bat | MORE

ECHO [config.sys]

TYPE C:\config.sys | MORE

ECHO [Dysk twardy C:]

LABEL

ECHO Naciśnij jakiś klawisz...

PAUSE

Aby wykonać powyŜszy plik naleŜy nadać mu nazwę z rozszerzeniem bat (moŜe być Info.bat) a

następnie w katalogu bieŜącym wpisać komendę będącą nazwą pliku wsadowego, czyli

odpowiednio:

C:\TEMP>info

Materiał znaleziony gdzieś w internecie

Interpreter wykonuje sekwencyjnie jedno po drugim wszystkie polecenia pliku wsadowego w

kolejności ich występowania. Pierwsza linia pliku (polecenie REM) jest komentarzem jest

komentarzem i podczas wykonywania nie jest brana pod uwagę. Dwie kolejne linie zawierają

polecenie ECHO, którego wykonanie polega na wypisaniu podanego tekstu na ekranie. Linie 4 i 6

zawierają polecenie MS-DOS wypisania na ekranie podanych plików (TYPE) z podziałem na strony

(MORE). Linia ostatnia zawiera polecenie PAUSE, którego wykonanie polega na wypisaniu tekstu

"Naciśnij jakiś klawisz, aby kontynuować..." i zatrzymaniu wykonywania pliku wsadowego do czasu naciśnięcia dowolnego klawisza.

Polecenie

ECHO

JeŜeli wykonamy plik wsadowy test.bat zawierający tylko jedną linię z komendą DIR, to na

ekranie zostaną wypisane dwie rzeczy:

C:\BATCH>test

C:\BATCH>dir

Wolumin w stacji dysków C nie ma etykiety

Numer seryjny woluminu: 364F-10E8

Katalog C:\BATCH

. <DIR> 00.08.04 20:42 .

.. <DIR> 00.08.04 20:42 ..

TEST BAT 3 00.08.04 20:43 test.bat

1 plik(ów) 3 bajtów

2 katalog(ów) 271 859 712 bajtów wolnych

C:\BATCH>_

Pierwsza linia zawiera tekst wydanej komendy. W linii drugiej interpreter wypisał treść polecenia

występującego w pliku wsadowym. Kolejne linie zawierają wynik wykonanania polecenia DIR.

Przykład ten pokazuje sposób postępowania podczas wykonywania pliku wsadowego -

command.com czyta linię pliku wsadowego, wypisuje ją na ekranie a następnie uruchamia

odpowiedni program lub polecenie wewnętrzne. Po zakończeniu wykonywania polecenia proces

się powtarza - odczyta kolejną linię, wypisze jej treść na ekranie a następnie uruchomi

odpowiedni program, itd.

Polecenie ECHO moŜna wydać z argumentem ON lub OFF. Instrukcja

ECHO OFF

powoduje wyłączenie wypisywania treści poleceń występujących w pliku wsadowym. Od

momentu wykonania tej instrukcji command.com nie będzie wypisywał treści przetwarzanych

komend a jedynie ich wyniki. Bardzo często instrukcję powyŜszą umieszcza się w pierwszej linii pliku

wsadowego.

UŜycie argumentu ON powoduje oczywiście włączenie wypisywania treści poleceń.

Materiał znaleziony gdzieś w internecie

Z analizy wydruku dowolnego pliku wsadowego zawierającego w pierwszej linii komendę ECHO

OFF moŜna wywnioskować, Ŝe wyłączone tą komendą wypisywanie treści poleceń obowiązuje

dopiero od linii drugiej - command.com zawsze wypisze treść pierwszej komendy pliku, czyli

ECHO OFF. Aby tego uniknąć naleŜy linię tą poprzedzić znakiem '@' ("at") - linia pliku, która poprzedzona jest tym znakiem nigdy nie jest wyświetlana na ekranie.

Podsumowując: istnieją dwie metody całkowitego wyłączenia wypisywania treści komend pliku

wsadowego:

1. umieszczenie w pierwszej linii komendy @ECHO OFF,

2. rozpoczynanie kaŜdej linii pliku znakiem '@'.

Instrukcja

warunkowa

(1)

Niemal wszystkie wykonywane programy podczas pracy są "zmuszane przez uŜytkownika" do podejmowania pewnych decyzji. Program niejednokrotnie musi decydować jakiego rodzaju

informacje powinien wyświetlić, czy w danym momencie zareagować na klawisze naciskane na

klawiaturze,

jaką

operację

naleŜy

wykonać,

czy

zakończyć

swoje

działanie,

itp.

Do podejmowania w programach tego typu decyzji słuŜy instrukcja warunkowa. W pliku

wsadowym instrukcja ta moŜe mieć jedną z trzech postaci.

IF EXIST plik komenda

albo

IF NOT EXIST plik komenda

Instrukcja w tej postaci pozwala na wykonananie dowolnego polecenia tylko wówczas, gdy

istnieje podany plik (lub gdy nie istnieje jeśli uŜyto NOT). RozwaŜmy dwie następujące komendy:

[1] DEL lista.txt > NUL

[2] IF EXIST lista.txt DEL lista.txt > NUL

Polecenie [1] jest oczywiste: usuń plik lista.txt. Polecenie [2] mówi: jeŜeli istnieje plik lista.txt, to usuń ten plik. Efekt końcowy obu poleceń jest taki sam - zostanie usunięty plik lista.txt. Pomiędzy

tymi poleceniami istnieje jednak pewna róŜnica; o poleceniu [2] moŜna by powiedzieć, Ŝe "jest lepsze". OtóŜ polecenie DEL usuwa podany plik i nie wyświetla Ŝadnych komunikatów o usunięciu

pliku, jeŜeli jednak usuwany plik nie istnieje, to wykonanie polecenia jest niemoŜliwe - zostanie wówczas wyświetlony komunikat o błędzie - mimo przekierowania wyjścia polecenia do pliku

pustego komunikat ów pojawi się na ekranie. Taka sytuacja nie będzie miała miejsca w przypadku

polecenia [2]: to polecenie bowiem wykona komendę DEL lista.txt tylko wówczas, gdy plik

lista.txt istnieje - jeŜeli w katalogu bieŜącym pliku nie ma, to komenda jest pomijana i na tym kończy się wykonanie całej instrukcji warunkowej.

Polecenie DEL moŜna tutaj zastąpić inną komendą, np:

[1] TYPE lista.txt

[2] IF EXIST lista.txt TYPE lista.txt

W tym wypadku mamy doczynienia z tą samą sytuacją: jeŜeli nie istnieje plik lista.txt, to

polecenie [1] wypisze komunikat o błędzie - nie zrobi tego natomiast polecenie [2].

Etykiety

i

instrukcja

skoku

GOTO

RozwaŜymy przkład trochę trudniejszy. NaleŜy utworzyć kopię pliku lista.txt pod nazwą lista.bak.

Tutaj równieŜ wskazane jest wykorzystanie instrukcji warunkowej:

@ECHO OFF

IF EXIST lista.txt COPY lista.txt lista.bak > NUL

Materiał znaleziony gdzieś w internecie

JeŜeli w katalogu bieŜącym istnieje plik lista.txt zostanie wykonane polecenie utworzenia jego kopii

pod

nazwą

lista.bak.

Konstruując powyŜszy plik naleŜy przewidzieć jeszcze jedną sytuację: w katalogu bieŜącym moŜe

równieŜ istnieć plik o nazwie lista.bak. Powstaje wówczas pytanie "co w tej sytuacji zrobi polecenie COPY?" - albo wyświetli komunikat o błędzie i nie wykona kopiowania, albo teŜ skopiuje

plik źródłowy usuwając przy tym zawartość istniejącego pliku docelowego - w pewnych

sytuacjach

obie

z

tych

moŜliwości

mogą

okazać

się

niezadawalające.

Istnieją oczywiście metody rozwiązania tego problemu za pomocą opcji polecenia COPY, warto

jednak pamiętać, Ŝe opcje poleceń często zmieniają się w róŜnych wersjach interpretera

command.com i komenda, która poprawnie wykonuje się na naszym komputerze moŜe w innej

wersji interpretera zostać uznana za niepoprawną z powodu błędnej opcji polecenia.

PowyŜszy przykład demonstruje problem wykonania komendy tylko wówczas, gdy spełnione są

dwa lub więcej określonych warunków - problemy tego typu rozwiązuje się na ogół za pomocą

instrukcji skoku GOTO.

Instrukcja:

:Etykieta

definiuje tzw. etykietę w pliku wsadowym. Etykieta to inaczej mówiąc słowna nazwa linii pliku, umieszczając instrukcję etykiety nazywamy linię pliku podaną po znaku ':' nazwą. Nazwa etykiety

powinna być jednym słowem nie zawierającym odstępów (moŜna połaczyć słowa znakiem '_') i

powinna rozpoczynać się tuŜ za znakiem ':', nie naleŜy rozdzielać nazwy i znaku ':' odstępami.

Podczas wykonywania pliku wsadowego interpreter pomija linie pliku zawierające etykiety

(podobnie jak ma ty miejsce w przypadku polecenia komentarza REM), instrukcji tej nie wykonuje

się, słuŜy ona jedynie do przenoszenia wykonywania pliku przez instrukcję skoku GOTO:

GOTO Etykieta

Wykonanie instrukcji skoku polega na przeniesieniu wykonywania pliku do tej linii w pliku, która

zawiera (jest nazwana) podaną etykietę (wpisujemy tutaj tylko nazwę etykiety, bez znaku ':').

Wróćmy teraz do przykładu usuwania pliku:

[1] @ECHO OFF

[2] IF EXIST lista.txt GOTO Usuwaj

[3] ECHO Nie ma takiego pliku...

[4] GOTO Koniec

[5] :Usuwaj

[6] ECHO Usuwanie pliku lista.txt...

[7] DEL lista.txt > NUL

[8] ECHO Wykonane...

[9] :Koniec

W linii [2] następuje sprawdzenie istnienia w katalogu bieŜącym pliku lista.txt.

JeŜeli plik istnieje wykonana zostanie komenda GOTO Usuwaj - nastąpi przejście (przeniesienie

wykonywania) do linii oznaczonej etykietą Usuwaj, czyli do linii [5]. Linia ta zostanie zignorowana

przez command.com, który rozpocznie wykonywanie pliku od linii następnej [6]. Wypisany

Materiał znaleziony gdzieś w internecie

zostanie tekst "Usuwanie pliku lista.txt...", następnie interpreter wykona linię [7] usuwając plik lista.txt, wypisze tekst "Wykonane..." i zakończy wykonywanie pliku na ostatniej linii [9].

Podczas wykonywania linii [2] moŜe się oczywiście okazać, Ŝe katalog bieŜący nie zawiera pliku lista.txt. Instrukcja warunkowa wówczas pominie podaną komendę GOTO Usuwaj i wykonana

zostanie komenda następna w linii [3] - wypisanie tekstu "Nie ma takiego pliku..." oraz komenda w

linii

[4]

-

przejście

do

etykiety

Koniec.

Warto jeszcze zwrócić uwagę na linię [4]. Brak tej linii spowodowałby wypisanie tekstu "Nie ma takiego pliku..." a następnie wykonanie komendy w liniach [6], [7] i [8], czyli pomimo nieistnienia

pliku byłyby wykonywane polecenia związane z jego usunięciem.

Plik wsadowy wykonujący wspomniane wcześniej kopiowanie pliku lista.txt na lista.bak mógłby

mieć postać:

@ECHO OFF

IF NOT EXIST lista.txt GOTO BrakPliku

IF EXIST lista.bak GOTO IstniejeKopia

ECHO Kopiowanie lista.txt na lista.bak...

COPY lista.txt lista.bak > NUL

ECHO Wykonane...

GOTO Koniec

:BrakPliku

ECHO Plik lista.txt nie istnieje...

GOTO Koniec

:IstniejeKopia

ECHO Plik lista.bak juŜ istnieje...

:Koniec

Argumenty

plików

wsadowych

Podobnie jak polecenia i programy pliki wsadowe moŜna uruchamiać z argumentami. Do

poszczególnych argumentów pliku moŜna się od odwoływać za pomocą symboli %1, %2, ..., %9,

które

reprezentują

odpowiednio

pierwszy,

drugi,

...,

dziewiąty

argument

pliku.

Przykład:

Napisać plik wsadowy mydel.bat, który usunie plik podany jako argument.

@ECHO OFF

IF EXIST %1 GOTO Usuwaj

Materiał znaleziony gdzieś w internecie

ECHO Plik %1 nie istnieje...

GOTO Koniec

:Usuwaj

ECHO Usuwanie pliku %1 ...

DEL %1 > NUL

ECHO Wykonane...

:Koniec

UWAGA: plik naleŜy uruchomić z argumentem będącym nazwą pliku - jego brak moŜe

spowodować błąd wykonania i w konsekwencji komunikat o wymaganym argumencie.

Interpreter podczas analizy linii pliku wszystkie wyraŜenia postaci %1, %2, ..., %9 zastępuje faktycznymi argumentami podanymi w linii komend:

C:\TEMP>mydel.bat lista.txt

Usuwanie pliku lista.txt ...

Wykonane...

C:\TEMP>_

Widać powyŜej, Ŝe w linii drugiej interpreter zamiast symbolu %1 wypisał faktycznie podany

argument w wywołaniu lista.txt. JeŜeli plik wsadowy uruchamiamy bez argumentów to wszystkie

wyraŜenia %1, %2, ..., %9 są napisami pustymi (napis nie zawierający Ŝadnych znaków). JeŜeli w

linii komend występuje N argumentów, to wyraŜenia %1, ..., %N reprezentują podane

argumenty,

wyraŜenia

%N+1,

%N+2,

...

są

natomist

napisami

pustymi.

Nasuwa się proste pytanie, czy plik wsadowy moŜna przetworzyć z dziesięcioma lub więcej

argumentami. Odpowiedź w zasadzie jest twierdząca, ale o tym nieco później...

Instrukcja

warunkowa

(2)

Druga postać instrukcji warunkowej dotyczy porównywania napisów:

IF "napis1" == "napis2" komenda

albo

IF NOT "napis1" == "napis2" komenda

Instrukcja w tej postaci powoduje wykonanie podanej komendy tylko wówczas, gdy oba napisy

napis1 i napis2 są równe, czyli takie same. Słowo równość oznacza tutaj równość idealną - napisy

musza mieć taką samą długość i składać się z takich samych znaków. W przypadku nazw plików i

katalogów duŜe i małe litery nie są rozróŜnialne, w przypadku porównywania napisów brane jest

to pod uwagę. Tak więc napisy "Lista.txt" oraz "lista.txt" wcale nie są równe.

Warto pamiętać, Ŝe bezpieczniej jest podawać porównywane napisy w cudzysłowie oraz pomiędzy

napisami a znakiem '=' umieścić znak odstępu - jego brak moŜe spowodować błąd wykonania

pliku.

Materiał znaleziony gdzieś w internecie

Ta postać instrukcji warunkowej posłuŜy nam przede wszystkim do sprawdzania ilości podanych

argumentów. Korzystając o obu postaci instrukcji moŜemy napisać ostateczną wersję pliku

wsadowego mydel.bat usuwającego plik podany jako argument, przyjmując przy tym następujące

załoŜenia:

• plik wsadowy moŜe być uruchomiony z argumentem '/?' - naleŜy wówczas wyświetlić

informację o przeznaczeniu oraz opis składni,

• uruchomienie pliku z jednym argumentem będącym nazwą pliku powoduje jego

usunięcie lub wypisaniu komunikatu o błędzie,

• jeŜeli plik został uruchomiony z dwoma lub większą ilością argumentów, to jeśli

pierwszym z nich jest '/?', to wyświetlamy informację o przeznaczeniu i składnię,

jeŜeli natomiast pierwszy argument jest nazwą pliku, to wypisujemy komunikat o

błędzie i składnię.

@ECHO OFF

REM

REM Usuwa plik podany jako argument

REM

IF "%1" == "/?" GOTO Informacja

IF "%1" == "" GOTO BrakArgumentu

IF NOT "%2" == "" GOTO ZbytWieleArgumentow

IF EXIST %1 GOTO Usuwaj

ECHO Plik [%1] nie istnieje.

GOTO Koniec

:Usuwaj

ECHO Usuwanie [%1]

DEL %1 > NUL

GOTO Koniec

:BrakArgumentu

ECHO Oczekiwany argument.

GOTO Skladnia

:ZbytWieleArgumentow

Materiał znaleziony gdzieś w internecie

ECHO Zbyt wiele argumentów.

GOTO Skladnia

:Informacja

ECHO Usuwa podany plik.

:Skladnia

ECHO Składnia polecenia:

ECHO MYDEL [/?] nazwa_pliku

:Koniec

Uff...

Mimo iŜ czynność jest stosunkowo prosta, to konstrukcja pliku wymaga sporego nakładu pracy.

Przeanalizujemy

krótko

poszczególne

warunki

zadania.

Z przyjętych załoŜeń wynika, Ŝe dopuszczalne są wywołania: "mydel /?", "mydel /? /?", "mydel /?

lista.txt", "mydel /? lista.txt lista.bak" - dopuszczalne jest kaŜde wywołanie, w którym pierwszy argument jest równy "/?". W związku z tym w pliku wsadowym w pierwszej kolejności

sprawdzamy

wystąpienie

tego

właśnie

argumentu.

Kolejne instrukcje warunkowe dotyczą juŜ przypadków uruchomienia bez argumentów lub z

argumentami, ale z pierwszym argumentem róŜnym od "/?". Sprawdzamy najpierw czy podano jakikolwiek

argument.

Trzecia istrukcja IF dotyczy przypadku: podano co najmniej jeden argument i argument pierwszy

jest nazwą pliku. Wówczas usuwamy plik jeŜeli jest to jedyny argument lub wypisujemy

komunikat o błędzie gdy podano więcej niŜ jedną nazwę pliku. Ilość podanych argumentów, a

właściwie to czy argument jest jeden, sprawdzamy porównując argument drugi %2 z napisem

pustym.

Ostatnie IF dotyczy juŜ tylko przypadku: podano dokładnie jeden argument będący nazwą pliku -

pozostaje więc sprawdzić czy podany plik istnieje.

Instrukcja

CALL

Jak wspomniano na początku w pliku wsadowym moŜna uŜywać dowolnych poleceń

wewnetrznych i programów wykonywalnych (com i exe). Polecenie pliku wsadowego nie moŜe

natomiast być plikiem wsadowym. Uruchomienie w pliku wsadowym innego pliku wsadowego

wymaga zastosowania polecenia:

CALL plik_wsadowy [argumenty]

Do tej pory stosowane były instrukcje skoku zawsze do etykiety połoŜonej "poniŜej" w pliku wsadowym. Istnieje moŜliwość przeniesienia wykonywania pliku do linii wcześniejszej, czyli

"powyŜej" - tego typu konstrukcję, tzn. etykietę oraz występującą poniŜej instrukcję skoku do tej właśnie

etykiety

nazywamy

pętlą.

Pętle często stosuje się w połączeniu z instrukcją SHIFT. Polecenie SHIFT wykonuje tzw.

przesunięcie argumentów, tzn. argument pierwszy %1 zastępowany jest przez argument drugi

%2, argument drugi %2 zastępowany jest przez argument trzeci %3, itd. Ogólnie: argument %N

zastępowany

jest

przez

argument

%(N+1).

UWAGA:

W wyniku wykonania polecenia argument pierwszy pliku wsadowego jest bezpowrotnie tracony -

nie ma moŜliwości odwołania się do tego argumentu. Demonstruje to poniŜszy przykład:

Materiał znaleziony gdzieś w internecie

@ECHO OFF

ECHO Arg1=[%1] Arg2=[%2] Arg3=[%3] Arg4=[%4]

SHIFT

ECHO Arg1=[%1] Arg2=[%2] Arg3=[%3] Arg4=[%4]

SHIFT

ECHO Arg1=[%1] Arg2=[%2] Arg3=[%3] Arg4=[%4]

SHIFT

ECHO Arg1=[%1] Arg2=[%2] Arg3=[%3] Arg4=[%4]

SHIFT

ECHO Arg1=[%1] Arg2=[%2] Arg3=[%3] Arg4=[%4]

SHIFT

ECHO Arg1=[%1] Arg2=[%2] Arg3=[%3] Arg4=[%4]

Tak wygląda wykonanie pliku z pięcioma argumentami:

C:\TEMP>argumen.bat list1.txt list2.txt list3.txt list4.txt list5.txt

Arg1=[list1.txt] Arg2=[list2.txt] Arg3=[list3.txt] Arg4=[list4.txt]

Arg1=[list2.txt] Arg2=[list3.txt] Arg3=[list4.txt] Arg4=[list5.txt]

Arg1=[list3.txt] Arg2=[list4.txt] Arg3=[list5.txt] Arg4=[]

Arg1=[list4.txt] Arg2=[list5.txt] Arg3=[] Arg4=[]

Arg1=[list5.txt] Arg2=[] Arg3=[] Arg4=[]

Arg1=[] Arg2=[] Arg3=[] Arg4=[]

Po pierwszym wykonaniu polecenia SHIFT wyraŜenie %1 reprezentuje juŜ napis list2.txt,

wyraŜenie %2 napis list3.txt i tak dalej. Po wykonaniu drugim wyraŜenie %1 jest równe list3.txt,

zaś %4 jest w ogóle napisem pustym - %4 musiałoby reprezentować szósty argument podany w

wywołaniu,

tymczasem

podano

tylko

pięć

argumentów.

Po piątym wywołaniu wszystkie argumenty mają wartość pustą!. Ogólnie: jeŜeli plik wsadowy

uruchomiony został z N argumentami, to po N-1 wykonaniu instrukcji SHIFT ostatni z podanych

argumentów znajduje się na miejscu %1, po wykonaniu N-tym plik wsadowy w ogóle nie ma

argumentów.

Oto prosty przykład pliku wsadowego argument.bat, który umieszcza w pliku o nazwie

argument.txt wszystkie podane argumenty, kaŜdy w osobnej linii.

@ECHO OFF

IF "%1" == "/?" GOTO Informacja

:Start

IF "%1" == "" GOTO Koniec

Materiał znaleziony gdzieś w internecie

ECHO %1 >> argument.txt

SHIFT

GOTO Start

:Informacja

ECHO Umieszcza w pliku argument.txt wszystkie podane argumenty.

ECHO Składnia polecenia:

ECHO ARGUMENT [/?] [arg1 arg2 ...]

:Koniec

Jeśli pierwszy argument jest równy "/?" zostanie wyświetlona pomoc. W pozostałych przypadkach

wykonywana

jest

pętla

od

etykiety

Start

do

instrukcji

skoku

GOTO

Start.

NajwaŜniejszą instrukcją kaŜdej pętli jest instrukcja przerwania pętli, czyli przeniesienia

wykonywania pliku poza pętlę. W tym wypadku zadanie to wykonuje polecenie IF, które sprawdza

niepustość argumentu %1. Cały cykl powtarzany jest tak długo aŜ argument %1 osiągnie wartość

napisu pustego. PoniewaŜ wewnątrz pętli występuje polecenie SHIFT w którymś momencie

skończą

się

argumenty

pliku

i

wykonywanie

pętli

zostanie

zakończone.

Konstruując pętlę naleŜy zawsze stworzyć warunki umoŜliwiające jej zakończenie. Nietrudno

przewidzieć jaki efekt moŜna osiągnąć po usunięciu z powyŜszego pliku instrukcji SHIFT. Wówczas

podczas wykonywania pętli argumenty nie ulegałyby Ŝadnym zmianom co oznacza, Ŝe pętla

mogłaby się nigdy nie skończyć. Ten sam skutek przyniosłoby usunięcie instrukcji wyjścia z pętli

IF. W tym wypadku argumenty do ich wyczerpania ulegałyby zmianom, nie wpłynęłoby to jednak

na instrukcję GOTO Start, która zawsze wykonywałaby skok do podanej etykiety. Taką sytuację

nazywamy często "zapętleniem lub powieszeniem programu".

JeŜeli uŜywamy w pliku wsadowym pętli wskazane jest przedsięwzięcie pewnych środków

ostroŜności. OtóŜ wykonanie pliku wsadowego moŜna przerwać naciskając klawisz Ctrl+C.

Wówczas command.com moŜe zareagować na naciśnięty klawisz i zakończyć wykonywanie pliku,

aby jednak było to moŜliwe naleŜy ustawić wykrywalność tego klawisza poleceniem:

BREAK ON

Polecenie to moŜna wydać na klawiaturze, albo umieścić w pliku wsadowym przed rozpoczęciem

pętli - najlepiej na początku pliku. Samo polecenie BREAK bez argumentu ON lub OFF wyświetla

jedynie

stan

reakcji

na

klawisz

Ctrl+C.

Warto pamiętać:

NIEOMYLNOŚĆ = FORMAT C:

co mniej więcej znaczy tyle, Ŝe kres wiary we własne umiejętności zawsze idzie w parze z utratą

części dysku.

Pętle wykorzystujemy na ogół, gdy określoną czynność trzeba wykonać na większej liczbie liczbie

plików. Mając do dyspozycji plik wsadowy mydel.bat usuwający jeden podany plik, zadanie

polegające na usunięciu wszystkich plików będących argumentami pliku wsadowego sprowadza

się wyłącznie do wywołania pliku mydel.bat taką ilość razy, ile plików mamy usunąć.

Przykład:

Napisać plik wsadowy usuwający wszystkie pliku podane w postaci argumentów.

@ECHO OFF

Materiał znaleziony gdzieś w internecie

BREAK ON

:Start

IF "%1" == "" GOTO Koniec

CALL mydel.bat %1

SHIFT

GOTO Start

:Koniec

Obsługę błędów oraz "pomoc" naleŜy dopisać samodzielnie.

Instrukcja

warunkowa

(3)

I

to

chyba

jest

ten

moment,

który

nazwać

moŜna

"wyŜszą

szkołą

jazdy"...

Ale najpierw trochę niezbędnej teorii.

Kiedy program kończy swoje działanie ma moŜliwość poinformowania systemu operacyjnego o

stanie swojego zakończenia. Przekazana informacja jest dosyć uboga albowiem moŜe być

zaledwie nieujemną liczbą całkowitą, ale o tym, Ŝe w świecie komputerów jedna liczba moŜe być

informacją bardzo obszerną nikogo przekonywać nie trzeba. Liczbę tą nazywamy kodem wyjścia

programu.

Z moŜliwości tej programy nie zawsze korzystają i często program nie pozostawia po sobie Ŝadnej

informacji - wówczas system operacyjny traktuje taki stan zakończenia jako poprawny i

przyjmuje, Ŝe zakończony program pozostawił po sobie kod zero (często mówimy teŜ, Ŝe program

zakończył się z kodem zero). Nie oznacza to wcale, Ŝe liczby róŜne od zera oznaczają błędne zakończenie programu; jest to często przyjmowana w informatyce reguła na mocy której liczba

zero oznacza poprawne wykonanie określonej operacji.

Instrukcja warunkowa w trzeciej postaci słuŜy właśnie do sprawdzania stanu zakończenia ostatnio

wykonanego programu lub komendy:

IF ERRORLEVEL kod_wyjścia komenda

albo

IF NOT ERRORLEVEL kod_wyjścia komenda

Kod_wyjścia jest tutaj liczbą naturalną, komenda poleceniem do wykonania. Instrukcja w tej

postaci wykona podaną komendę tylko wówczas, gdy ostatnio wykonywane polecenie zwróciło

kod wyjścia większy lub równy podanej liczbie (w przypadku uŜycia NOT mniejszy od podanej

liczby).

Z tej postaci instrukcji warunkowej korzystać będziemy wyłącznie przy sprawdzaniu kodu wyjścia

polecenia CHOICE, które stosuje się w systemie MS-DOS do zadawania róŜnego rodzaju pytań.

Składnia polecenia jest następująca:

CHOICE [/C:odpowiedzi] [/N] [/T:Z,XY] [tekst]

Co robi polecenie CHOICE? Po wydaniu komendy CHOICE bez argumentów na ekranie zostanie

wyświetlony napis "[T,N]?" a następnie program będzie czekał do momentu naciśnięcia jednej z

liter 'T' lub 'N'. Wydanie polecenia w postaci CHOICE /C:12A* spowoduje wypisanie tekstu

"[1,2,A,*]?" i oczekiwanie programu na naciśnięcie któregoś z podanych znaków. JeŜeli podamy określony tekst, to program wypisze go a następnie wyświetli listę dopuszczalnych odpowiedzi.

UŜycie opcji "/N" spowoduje, Ŝe nie zostanie wyświetlona lista odpowiedzi, opcja "/T" określa

Materiał znaleziony gdzieś w internecie

odpowiedź

domyślną

Z

po

XY

sekundach.

Po wydaniu polecenia:

CHOICE /C:ABX /N /T:0,5 "Rodzaj szkoły? [A-podst, B-średn, X-Ŝadna] : "

na ekranie pojawi się tekst "Rodzaj szkoły? [A-podst, B-średn, X-Ŝadna] : " a następnie program będzie czekał na naciśnięcie jednego z klawiszy A, B, X przez maksymalnie 5 sekund -

niewybranie Ŝadnej z odpowiedzi jest równoznaczne z wybraniem odpowiedzi domyślnej, czyli

odpowiedzi

X.

Program po wyborze odpowiedniego klawisza bądź po upływie dopuszczalnego czasu kończy

swoje działanie zwracając do systemu operacyjnego kod wyjścia, który jest numerem odpowiedzi

na podanej liście, tzn. po wyborze A program zwróci 1, po wyborze B liczbę 2, zaś po wyborze X

liczbę 3.

Przykład:

Napisać plik wsadowy, który będzie potrafił uruchomić jeden z trzech programów w zaleŜności od

wyboru uŜytkownika, np. Norton Commander lub Windows.

@ECHO OFF

:Start

CLS

ECHO _

ECHO _

ECHO [ 1 ]. Norton Commander

ECHO [ 2 ]. Turbo Pascal

ECHO [ 3 ]. Windows

ECHO [ Q ]. Zakończ

ECHO _

ECHO _

CHOICE /C:123Q /N "Wybierz program do uruchomienia : "

IF ERRORLEVEL 4 GOTO Koniec

IF ERRORLEVEL 3 GOTO Windows

IF ERRORLEVEL 2 GOTO Pascal

ECHO Trwa uruchamianie Norton Commandera...

C:\NC\NC.EXE

GOTO Start

:Windows

Materiał znaleziony gdzieś w internecie

ECHO Trwa uruchamianie systemu Windows...

C:\WINDOWS\WIN.COM

GOTO Koniec

:Pascal

ECHO Trwa uruchamianie Turbo Pascala...

C:\TP7\TURBO.EXE

GOTO Start

:Koniec

Linie zawierające polecenie ECHO z kreską podkreślenia naleŜy wpisać w następujący sposób: po

wpisaniu słowa ECHO naleŜy wpisać klawisz spacji a następnie nacisnąć i przytrzymać klawisz Alt i

przy wciśniętym klawiszu Alt na klawiaturze numerycznej (z prawej strony) wpisać kod znaku 255

po czym moŜna zwolnić klawisz Alt - kursor powinien się wówczas przesunąć o jedną pozycję w

lewo, a wszystko to po to, aby zmusić polecenie ECHO do wypisania pustej linii.

Podane w pliku ściezki dostępu muszą oczywiście być poprawne - moŜna je nawet zmienić na

ścieŜki do innych programów.

Zwrócmy uwagę na kolejność sprawdzania kodu wyjścia polecenia CHOICE. Instrukcje

warunkowe porównują kod wyjścia od wartości największej moŜliwej czyli 4 w dół do wartości

przedostatniej 2 - pominięcie wszystkich IF jest równowaŜne z wyborem odpowiedzi pierwszej.

Taki sposób sprawdzania wartości kodu jest konsekwencją sposobu wykonywania instrukcji

warunkowej - jeŜeli w pierwszej instrukcji IF umieścilibyśmy kod 2, to spełnienie tego warunku mówiłoby tylko tyle, Ŝe wybrano odpowiedź 2, 3 lub 4. MoŜna przyjąć, Ŝe sprawdzanie kodu

wyjścia zawsze wykonujemy w ten sam sposób od wartości największych do najmniejszych - choć

oczywiście

moŜna

wykonać

to

inaczej.

Pozostaje tylko dodać, Ŝe uruchomienia systemu Windows podczas pracy Windows jest raczej

niewykonalne i zakończy się odpowiednim komunikatem. MoŜna to jednak zrobić podczas pracy

trybu MS-DOS (tryb MS-DOS jest czymś innym niŜ Wiersz poleceń). Kto zamierza to sprawdzić,

powinien odnaleźć plik C:\autoexec.bat i w ostatnim wierszu tego pliku wpisać polecenie

uruchamiające powyŜszy plik wsadowy, czyli np. CALL C:\TEMP\mymenu.bat, po czym wykonać

"reboot" komputera.

Przykład:

Jako drugi przykład wykorzystania trzeciej postaci instrukcji warunkowej napiszemy plik wsadowy

zmieniający nazwę pliku. Obsługę błędów oraz informacje o przeznaczeniu naleŜy uzupełnić

samodzielnie.

@ECHO OFF

BREAK ON

:Usuwaj

IF NOT EXIST %2 GOTO MoznaZmienic

CHOICE /C:TN "Plik %2 juŜ istnieje. Usunąć istniejący plik "

Materiał znaleziony gdzieś w internecie

IF ERRORLEVEL 2 GOTO Koniec

DEL %2 > NUL

:MoznaZmienic

ECHO Przenoszenie %1 na %2

REN %1 %2 > NUL

GOTO Koniec

:Koniec

Przejście do etykiety Usuwaj powinno nastąpić w sytuacji gdy podano dwa argumenty będące

nazwami plików i argument pierwszy jest nazwą istniejącego pliku. Wówczas jeŜeli nie istnieje plik

podany jako drugi argument, to zmieniamy nazwę pliku, w przeciwnym wypadku zadajemy

pytanie czy usunąć istniejący plik. Po odpowiedzi negatywnej przechodzimy na koniec pliku

wsadowego, w przypadku odpowiedzi pozytywnej usuwamy istniejący plik i wykonujemy zmianę

nazwy.

Instrukcja

iteracyjna

FOR

Instrukcje iteracyjne (powtarzające, zwane teŜ pętlami) słuŜą w językach programowania do

wielokkrotnego wykonywania podobnych czynności. Ogólnie dzieli się instrukcje iteracyjne na

pętle o znanej lub niemoŜliwej do przewidzenia z góry liczbie powtórzeń. Sformułowanie "o znanej

liczbie powtórzeń" wymaga pewnego wyjaśnienia. Przez znaną ilość iteracji rozumie się tu ilość znaną nie w momencie pisania programu lub pliku wsadowego, tylko ilość znaną w momencie

rozpoczęcia wykonywania pętli. I tak na przykład: jeŜeli pętla zostanie powtórzona tyle razy ile plików zawiera katalog bieŜący, to mimo iŜ nie moŜemy przewidzieć ile plików będzie zawierał

katalog traktujemy tą pętlę jako pętlę o znanej liczbie powtórzeń - liczba tą będzie bowiem znana

w momencie rozpoczynania pętli. RównieŜ omówiony wcześniej przykład pliku wsadowego, który

usuwał wszystkie pliki podane jako argumenty jest przykładem pętli o znanej liczbie powtórzeń -

plik moŜna uruchomić z kaŜdą liczbą argumentów, niemniej jednak liczba ta zawsze jest znana w

momencie

uruchomienia

pliku

wsadowego.

A oto przykład pętli o niemoŜliwej do ustalenia z góry liczbie powtórzeń:

:Start

CHOICE /C:TN "Powtórzyć ?"

IF ERRORLEVEL 2 GOTO Koniec

GOTO Start

:Koniec

Przerwanie pętli następuje w momencie naciśnięcia klawisza 'N' - nie moŜna z góry przewidzieć ile

razy uŜytkownik wybierze odpowiedź 'T'.

Instrukcja iteracyjna FOR pliku wsadowego jest pętlą o znanej liczbie powtórzeń i następującej składni:

FOR %%X IN (lista) DO komenda

Materiał znaleziony gdzieś w internecie

Argument lista jest obowiązkowy i zawiera pooddzielane znakami odstępu nazwy plików - w

nazwach tych mogą występować znaki wieloznaczne '?' i '*'. Po znakach '%%' pojemy tzw.

zmienną - odpowiednik niewiadomej w matematyce. Zmienna ta będzie kolejno przybierać

wszystkie moŜliwe wartości spośród wartości podanych na liście (lista). Dla kaŜdej moŜliwej

wartości zmiennej X zostanie wykonane polecenie komenda.

RozwaŜmy przykład:

[1] FOR %%A IN (1 2 3) DO DIR

[2] FOR %%K IN (zadanie zadanie.bat zadanie.bak) DO DIR

KaŜda z powyŜszych instrukcji przyniesie ten sam efekt - trzy razy zostanie wykonane polecenie DIR. W przykładzie [1] zmienna A przybierze (otrzyma) wartość "1" a nastepnie nastąpi wykonanie polecenia DIR. Po wykonaniu komendy zmienna A otrzyma wartość "2" i ponownie nastąpi wykonanie komendy. po jej zakończeniu zmienna A otrzyma wartość "3" i zostanie wykonana

komenda.

Na

tym

zakończy

się

wykonywanie

polecenia

FOR.

W przykładzie [2] będzie dokłądnie tak samo z tą tylko róŜnicą Ŝe zmienna będzie przyjmować wartości "zadanie", "zadanie.bat" oraz "zadanie.bak".

Odpowiedź na pytanie po co zmienna przyjmuje wartości z listy staje się oczywista jeśli powiemy,

Ŝe wyraŜenie %%X moŜe występować w treści podanej komendy i reprezentuje aktualną wartość

zmiennej X, podobnie jak %1 reprezentuje pierwszy argument pliku wsadowego. Tak więc,

wykonanie polecenia:

FOR %%A IN (1 2 3 4 5 6 7 8 9 0) DO ECHO Wartość zmiennej = %%A

spowoduje wypisanie dziesięciu linii zawierających tekst "Wartość zmiennej = " oraz odpowiednią cyfrę

z

listy.

Polecenie

FOR %%A IN (*.txt *.bak) DO COPY %%A C:\TEMP

skopiuje wszystkie pliki z katalogu bieŜącego z rozrzerzeniami txt lub bak do podanego katalogu

C:\TEMP.

Zadania do samodzielnego rozwiązania

Wszystkie pliki wsadowe powinny działać we wszystkich moŜliwych przypadkach związanych z

istnieniem plików. NaleŜy równieŜ zadbać o to, aby podczas wykonywania plików wyświetlane

były wyłącznie informacje wypisywane przez polecenie ECHO pliku wsadowego.

1. Napisać plik wsadowy, który zmieni nazwę pliku (np. lista.txt) na taką samą, ale z

innym rozszerzeniem.

2. Napisać plik wsadowy, który połączy dwa dowolnie wybrane pliki w jeden plik o

nazwie wynik.txt.

3. Napisać plik wsadowy, który zamieni zawartość dwóch dowolnie wybranych plików.

4. Korzystając m.in. z poleceń find oraz sort napisać plik wsadowy mydir.bat, który

wyświetli zawartość katalogu bieŜącego. Na wydruku powinny być widoczne tylko

pliki i katalogi. Wydruk powinien zawierać w pierwszej kolejności listę plików a

następnie listę katalogów. Zarówno pliki jak i katalogi naleŜy posortować

alfabetycznie. Nie wolno korzystać z Ŝadnych opcji polecenia dir, moŜna natomiast

skorzystać z tymczasowych plików pomocniczych.

5. Napisać plik wsadowy mycopy.bat słuŜący do tworzenia kopii pliku pod inną nazwą,

przyjmując następujące załoŜenia:

o plik działa tylko w przypadku gdy został uruchomiony z dwoma

róŜnymi argumentami,

Materiał znaleziony gdzieś w internecie

o jeŜeli plik o takiej nazwie jak nazwa kopii juŜ istnieje, to nie

wykonujemy kopiowania.

6. Napisać plik wsadowy myren.bat słuŜący do zmiany nazwy na nazwę podaną,

przyjmując następujące załoŜenia:

o plik działa tylko w przypadku gdy został uruchomiony z dwoma

argumentami,

o jeŜeli oba argumenty są takie same, to jeśli plik istnieje nie

wykonujemy Ŝadnych czynności, jeśli natomiast pliku nie ma

wypisujemy komunikat o błędzie,

o jeŜeli plik o takiej nazwie jak nowa nazwa pliku juŜ istnieje, to

wypisujemy komunikat o błędzie.

7. Napisać plik wsadowy mycopy.bat słuŜący do tworzenia kopii pliku pod inną nazwą,

przyjmując następujące załoŜenia:

o plik moŜe być uruchomiony z dowolną ilością argumentów,

o jeŜeli nie podano argumentów wypisujemy składnię,

o jeŜeli pierwszy argument jest równy "/?" wypisujemy informację o

przeznaczeniu i składnię,

o jeŜeli podano argumenty i pierwszy z nich nie jest równy "/?" to

próbujemy wykonać kopiowanie gdy podano dokładnie dwa róŜne

argumenty, w przeciwnym wypadku (gdy podano więcej niŜ dwa,

gdy podano jeden argument lub gdy argumenty są dwa, ale takie

same) wypisujemy komunikat o błędzie,

o jeŜeli plik o takiej nazwie jak nazwa kopii juŜ istnieje, to nie

wykonujemy kopiowania.

8. Napisać plik wsadowy myren.bat słuŜący do zmiany nazwy pliku pod podaną,

przyjmując następujące załoŜenia:

o plik moŜe być uruchomiony z dowolną ilością argumentów,

o jeŜeli nie podano argumentów wypisujemy składnię,

o jeŜeli pierwszy argument jest równy "/?" wypisujemy informację o

przeznaczeniu i składnię,

o jeŜeli podano argumenty i pierwszy z nich nie jest równy "/?" to

próbujemy zmienić nazwę gdy podano dokładnie dwa argumenty, w

przeciwnym wypadku (gdy podano więcej niŜ dwa, gdy podano

jeden argument lub gdy argumenty są dwa, ale takie same)

wypisujemy komunikat o błędzie,

o jeŜeli plik o takiej nazwie jak nazwa kopii juŜ istnieje, to usuwamy

go, a następnie wykonujemy zmianę nazwy pliku,

o jeŜeli argumenty są dwa i są takie same oraz plik istnieje, to efekt

powinien być taki, jakgdyby zmieniono nazwę pliku.