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.