1/45
Interpreter poleceń cmd.exe
Slajd przedstawia architekturę interpretera wiersza poleceń cmd.exe w systemach operacyjnych z rodziny Windows NT oraz jego rolę w automatyzacji zadań.

Czym jest wiersz poleceń?

  • Rola interpretera systemowego: program wiersza poleceń cmd.exe przetwarza instrukcje użytkownika oraz uruchamia skrypty wsadowe w środowisku Windows NT.
  • Geneza architektoniczna: bezpośredni następca powłoki COMMAND.COM z systemów MS-DOS, dostosowany do wielozadaniowej architektury 32 i 64-bitowej.
  • Tryb interaktywny i wsadowy: możliwość wprowadzania pojedynczych instrukcji w konsoli lub przetwarzania wieloliniowych plików automatyzacji.
  • Współczesne zastosowanie: utrzymanie procesów ciągłej integracji, skrypty logowania domenowego oraz kompatybilność ze starszym oprogramowaniem.
  • Spis poleceń: https://ss64.com/nt/syntax.html
Wiersz poleceń (cmd.exe): domyślny proces interpretera poleceń w systemach z rodziny Windows NT, uruchamiany w przestrzeni użytkownika. Zapewnia interfejs tekstowy do interakcji z podsystemem Win32 oraz wykonywania skryptów wsadowych z rozszerzeniami .bat i .cmd. W przeciwieństwie do powłoki PowerShell przetwarza dane wyłącznie w postaci strumieni tekstowych, a nie obiektów środowiska .NET.
:: Uruchom wiersz poleceń (cmd.exe) i wpisz te komendy

:: Wyświetla wersję systemu Windows
ver

:: Wyświetla listę plików i katalogów
dir

:: Wyświetla konfigurację sieciową
ipconfig

:: Czyści ekran konsoli
cls
2/45
Pliki .bat vs .cmd
Slajd wyjaśnia różnice historyczne i semantyczne pomiędzy formatami plików wsadowych .bat i .cmd w środowisku Windows.

Pliki wsadowe (batch files)

  • Format wsadowy .bat: historyczne rozszerzenie wywodzące się z MS-DOS, zachowane dla maksymalnej zgodności wstecznej.
  • Format wsadowy .cmd: standard wprowadzony w Windows NT dedykowany dla interpretera cmd.exe z ulepszoną obsługą błędów.
  • Różnica w zmiennej ERRORLEVEL: w plikach .cmd kod błędu jest zerowany po pomyślnych poleceniach wbudowanych (np. PATH, SET), w .bat zachowuje stan poprzedni.
  • Zalecenie techniczne: w nowoczesnych systemach operacyjnych Windows zaleca się stosowanie rozszerzenia .cmd dla nowych skryptów automatyzacji.
Plik wsadowy (batch file): plik tekstowy zawierający sekwencję poleceń interpretera, wykonywanych automatycznie krok po kroku przez cmd.exe. Pozwala na automatyzację powtarzalnych zadań konfiguracyjnych, kompilacyjnych oraz administracyjnych w systemie operacyjnym. Skrypty wsadowe nie wymagają uprzedniej kompilacji do kodu maszynowego.
   +----------------------+
   | Plik tekstowy        |
   | (np. moj_skrypt.cmd) |
   +----------------------+
             |
             | Zawiera listę
             | poleceń
             v
   [ polecenie 1 ]
   [ polecenie 2 ]
   [ polecenie 3 ]
             |
             | Jest czytany linia
             | po linii przez...
             v
   +----------------------+
   | Interpreter cmd.exe   |
   +----------------------+
             |
             | ...który wykonuje
             | polecenia w systemie
             v
   +----------------------+
   |   System Operacyjny   |
   +----------------------+
            
3/45
Nasz pierwszy skrypt: witaj, świecie!
Slajd prezentuje konstrukcję elementarnego skryptu wsadowego, zasady ukrywania echa komend oraz techniki komentowania kodu.

Struktura podstawowego skryptu

  • Dyrektywa @echo off: wyłącza wyświetlanie treści poleceń na ekranie konsoli, prezentując użytkownikowi wyłącznie wygenerowane wyniki.
  • Znak ucieczki małpy (@): zapobiega wypisaniu na ekranie samego polecenia echo off podczas startu skryptu.
  • Składnia komentarzy: oficjalne polecenie REM (remark) oraz idiomatyczna, szybsza konstrukcja podwójnego dwukropka (::).
  • Zatrzymanie wykonania: polecenie pause wstrzymuje bieg programu do momentu naciśnięcia dowolnego klawisza przez operatora.
Dyrektywa echo off: polecenie sterujące interpretera cmd.exe wyłączające mechanizm powielania (echa) wprowadzanych instrukcji na standardowym strumieniu wyjściowym. Użycie prefiksu @echo off sprawia, że samo polecenie inicjujące również nie pojawia się w oknie terminala, co jest branżowym standardem estetyki skryptów wsadowych.
@echo off
REM To jest moj pierwszy skrypt wsadowy.
:: Uzywam obu typow komentarzy dla demonstracji.

echo Witaj, swiecie!
echo.
echo To jest prosty skrypt demonstrujacy podstawowe komendy.
echo.

echo Nacisnij dowolny klawisz, aby zakończyć...
pause
4/45
Uruchamianie skryptu i dobre praktyki
Slajd omawia metody uruchamiania skryptów wsadowych w systemie Windows oraz zasady bezpiecznego zarządzania uprawnieniami.

Jak uruchomić skrypt?

  • Uruchomienie interaktywne: dwukrotne kliknięcie pliku w Eksploratorze Windows uruchamia tymczasowe okno konsoli, które zamyka się po zakończeniu pracy.
  • Uruchomienie z poziomu wiersza poleceń: jawne wywołanie skryptu w otwartym terminalu cmd.exe pozwala zachować historię i komunikaty błędów.
  • Podniesienie uprawnień: uruchomienie w trybie administratora (UAC) jest wymagane przy operacjach na katalogach systemowych i rejestrze.
  • Harmonogram zadań: planowanie cyklicznego wykonywania skryptów w tle za pomocą systemowej usługi Task Scheduler.
Kontrola konta użytkownika (UAC): mechanizm bezpieczeństwa systemu Windows wymagający jawnego potwierdzenia lub podniesienia uprawnień do poziomu konta administratora przed wykonaniem operacji wpływających na globalną konfigurację systemu lub chronione zasoby dyskowe.
@echo off
setlocal
:: Wszystkie zmienne beda lokalne

title Moj Pierwszy Skrypt

echo Sprawdzam aktualną zmienną TEST_VAR...
echo Wartość: %TEST_VAR%
echo.

set TEST_VAR=To jest wartość ze skryptu
echo Ustawilem TEST_VAR na: %TEST_VAR%
echo.

echo Po zakończeniu TEST_VAR powróci do poprzedniego stanu.
pause

endlocal
:: Od tego momentu TEST_VAR wraca do oryginalnej wartości.
5/45
Zmienne: deklaracja i dostęp
Slajd przedstawia zasady deklarowania zmiennych w cmd.exe, mechanizm dostępu przez znaki procentu oraz pułapkę spacji w poleceniu set.

Przechowywanie danych

  • Polecenie set: służy do definiowania zmiennych środowiskowych i przypisywania im wartości tekstowych w bieżącym procesie.
  • Dostęp przez %ZMIENNA%: odczytanie wartości zmiennej wymaga otoczenia jej nazwy znakami procentu.
  • Pułapka spacji wokół znaku =: spacje przed lub po znaku równości stają się integralną częścią nazwy zmiennej lub jej wartości.
  • Zalecana notacja z cudzysłowami: zapis set "ZMIENNA=WARTOŚĆ" gwarantuje brak doklejania niewidocznych spacji na końcu linii.
Zmienna środowiskowa: nazwany obszar pamięci powiązany z procesem cmd.exe, przechowujący dane w formacie łańcucha znaków tekstowych. Zmienne mogą być dziedziczone przez procesy potomne wywoływane ze skryptu, lecz zmiany w nich dokonane nie wpływają domyślnie na nadrzędne środowisko systemowe po zakończeniu działania powłoki.
@echo off
setlocal

set USER_NAME=JanKowalski
set LOG_FILE=C:\Logs\%USER_NAME%.log
set APP_VERSION=1.2.3

echo Witaj, %USER_NAME%!
echo.
echo Wersja aplikacji: %APP_VERSION%
echo Sciezka do logu: %LOG_FILE%
echo.

:: Łączenie zmiennych
set GREETING=Cześć, %USER_NAME%!
echo %GREETING%
echo.

:: Sprawdzenie czy zmienna istnieje
if defined USER_NAME (
    echo Zmienna USER_NAME jest zdefiniowana.
)

:: Usuwanie zmiennej
set USER_NAME=
if not defined USER_NAME (
    echo Zmienna USER_NAME została usunięta.
)

pause
endlocal
6/45
Zmienne lokalne i globalne
Slajd wyjaśnia pojęcie zasięgu zmiennych oraz rolę poleceń setlocal i endlocal w hermetyzacji środowiska skryptu.

Zasięg zmiennych (scope)

  • Zasięg globalny: domyślnie zmienne tworzone przez skrypt modyfikują bieżącą sesję cmd.exe i pozostają w niej po zakończeniu skryptu.
  • Polecenie setlocal: tworzy lokalną kopię tablicy zmiennych środowiskowych, izolując wszelkie przyszłe modyfikacje wewnątrz bloku.
  • Polecenie endlocal: kończy blok lokalny, przywracając stan zmiennych i katalogu roboczego sprzed wywołania setlocal.
  • Automatyczne czyszczenie: zakończenie pliku wsadowego niejawnie wywołuje endlocal dla wszystkich aktywnych bloków setlocal.
Lokalizacja środowiska (setlocal): mechanizm interpretera cmd.exe tworzący kopię stanu środowiska wykonawczego. Wszelkie zmiany zmiennych oraz opcji powłoki (w tym opóźnionego rozszerzania i rozszerzeń poleceń) dokonane po instrukcji setlocal są usuwane w momencie napotkania odpowiadającego mu polecenia endlocal.
@echo off
setlocal

:: Zmienna globalna - zdefiniowana PRZED setlocal
set GLOBAL_VAR=Treść globalna

:: Zmienna lokalna - zdefiniowana PO setlocal
set LOKALNA_VAR=Treść lokalna

echo === Wewnątrz skryptu ===
echo GLOBAL_VAR = %GLOBAL_VAR%
echo LOKALNA_VAR = %LOKALNA_VAR%
echo.

:: Demonstracja zagnieżdżania setlocal
setlocal
    set LICZNIK=200
    echo === Wewnątrz zagnieżdżonego setlocal ===
    echo LICZNIK = %LICZNIK%
endlocal

echo Po zagnieżdżonym endlocal:
echo LICZNIK = %LICZNIK%

pause
:: Po zakończeniu skryptu zmienne lokalne zostaną usunięte
endlocal
7/45
Przekazywanie zmiennych przez endlocal
Slajd przedstawia sprawdzony idiom przekazywania danych ze strefy lokalnej setlocal do środowiska zewnętrznego za pomocą jednoczesnego wywołania endlocal i set.

Zwracanie wartości z lokalnego bloku

  • Problem zniszczenia zmiennych: polecenie endlocal natychmiast usuwa wszystkie zmienne utworzone po instrukcji setlocal.
  • Kolejność ewaluacji parsera: interpreter cmd.exe rozwija zmienne w całej linii przed wykonaniem jakiegokolwiek polecenia z tej linii.
  • Idiom jednej linii: zastosowanie spójnika & w konstrukcji endlocal & set "WYNIK=%LOKALNA%" pozwala wyprowadzić wartość.
  • Praktyczne zastosowanie: technika ta jest fundamentem tworzenia funkcji i podprogramów zwracających wyniki w języku wsadowym.
Idiom endlocal & set: specyficzna konstrukcja składniowa języka wsadowego wykorzystująca fakt, że interpreter odczytuje i podstawia wartości zmiennych (%ZMIENNA%) w całej linii przed uruchomieniem komendy endlocal. Dzięki temu zmienna zewnętrzna otrzymuje wyliczoną wartość tuż przed przywróceniem poprzedniego stanu środowiska.
@echo off
setlocal

:: Obliczamy jakąś wartość
set CALC_RESULT=0
set /a CALC_RESULT=15 * 3

echo Wewnątrz setlocal: CALC_RESULT = %CALC_RESULT%
echo.

:: Przekazanie wartosci na zewnatrz
:: Ta linia jest kluczowa!
endlocal & set "CALC_RESULT=%CALC_RESULT%"

:: Po zakończeniu skryptu zmienna nadal istnieje
echo Po endlocal: CALC_RESULT = %CALC_RESULT%
echo.

:: Przekazywanie wielu zmiennych naraz
setlocal
set VAR1=Wartosc 1
set VAR2=Wartosc 2
set VAR3=Wartosc 3
echo Wewnątrz: %VAR1%, %VAR2%, %VAR3%

endlocal & set "VAR1=%VAR1%" & set "VAR2=%VAR2%" & set "VAR3=%VAR3%"
echo Po endlocal: %VAR1%, %VAR2%, %VAR3%

pause
8/45
Wczytywanie danych od użytkownika
Slajd omawia pobieranie danych wprowadzanych przez użytkownika za pomocą polecenia set z przełącznikiem /p oraz walidację wejścia.

Polecenie set /p

  • Przełącznik /p: zatrzymuje wykonywanie skryptu i oczekuje na wpisanie łańcucha znaków zakończonego klawiszem Enter.
  • Monit zachęty (prompt): tekst umieszczony po znaku równości jest wyświetlany użytkownikowi jako zachęta do wprowadzania danych.
  • Zachowanie przy pustym wejściu: jeżeli użytkownik naciśnie wyłącznie Enter, zmienna zachowuje swoją dotychczasową wartość.
  • Konieczność walidacji: wartości wprowadzone przez użytkownika muszą być sprawdzane pod kątem obecności znaków specjalnych i pustych ciągów.
Polecenie set /p: wbudowane polecenie interpretera cmd.exe służące do interaktywnego pobierania danych z wiersza poleceń. Przypisuje pojedynczą linię tekstu wprowadzoną ze standardowego wejścia do wskazanej zmiennej, wyświetlając opcjonalny komunikat zachęty.
@echo off
setlocal

echo === Kreator raportu ===
echo.

:: Prośba o nazwę serwera
set /p SERVER_NAME=Podaj nazwe serwera: 

:: Sprawdź czy użytkownik coś podał
if not defined SERVER_NAME (
    echo Błąd: Nie podano nazwy serwera!
    goto :koniec
)

:: Prośba o adres IP
set /p SERVER_IP=Podaj adres IP serwera %SERVER_NAME%: 

:: Prosta walidacja
echo %SERVER_IP% | findstr /r "^[0-9.]*$" > nul
if errorlevel 1 (
    echo Uwaga: Adres IP moze byc niepoprawny.
)

echo.
echo --- Podsumowanie ---
echo Nazwa serwera: %SERVER_NAME%
echo Adres IP:      %SERVER_IP%
echo --------------------

:koniec
pause
endlocal
9/45
Zmienne wbudowane i dynamiczne
Slajd przedstawia zestaw wbudowanych zmiennych dynamicznych systemu Windows oraz metody ich odczytu w skryptach wsadowych.

Przydatne zmienne dostarczane przez system

  • Informacje czasowe (%DATE%, %TIME%): zawierają bieżącą datę i czas systemowy w formacie zależnym od ustawień regionalnych.
  • Zmienna losowa (%RANDOM%): generuje pseudolosową liczbę całkowitą z zakresu od 0 do 32767 przy każdym odczycie.
  • Identyfikacja środowiska (%CD%, %USERNAME%): udostępniają bieżący katalog roboczy oraz nazwę zalogowanego użytkownika.
  • Informacje o sprzęcie (%NUMBER_OF_PROCESSORS%): określają liczbę dostępnych rdzeni procesora w systemie operacyjnym.
Zmienna dynamiczna cmd.exe: specjalna zmienna pseudo-środowiskowa generowana w locie przez interpreter cmd.exe przy każdym odwołaniu. Nie występuje w fizycznym bloku środowiska procesu (nie jest widoczna w czystym poleceniu set), lecz zwraca aktualny stan zegara, generatora losowego lub kontekstu wykonania.
@echo off
setlocal

echo Skrypt uruchomiony w katalogu:
echo %CD%
echo.

echo Aktualna data i godzina:
echo Data: %DATE%
echo Czas: %TIME%
echo.

echo Losowa liczba: %RANDOM%
echo Losowa z zakresu 1-100:
set /a LOSOWA = (RANDOM %% 100) + 1
echo %LOSOWA%
echo.

:: Sprawdzenie ERRORLEVEL
dir > nul
echo Errorlevel po 'dir': %ERRORLEVEL%

dir C:\nie\ma\takiego\pliku.txt > nul 2> nul
echo Errorlevel po błędnym 'dir': %ERRORLEVEL%

echo.
echo Linia polecen: %CMDCMDLINE%

pause
endlocal
10/45
Rozszerzanie zmiennych w blokach kodu
Slajd wyjaśnia architekturę dwufazowego przetwarzania kodu w cmd.exe oraz pułapkę ewaluacji zmiennych %VAR% w blokach nawiasowych.

Pułapka natychmiastowego rozszerzania

  • Jednorazowe parsowanie bloków: interpreter czyta cały blok ujęty w nawiasy (...) jednorazowo przed wykonaniem pierwszej instrukcji.
  • Natychmiastowe podstawienie (%VAR%): wartości zmiennych w notacji procentowej są wstawiane w fazie parsowania całego bloku.
  • Niewidoczność zmian w pętli: modyfikacja zmiennej wewnątrz pętli for lub bloku if nie zmienia wartości odczytywanej przez %VAR%.
  • Objawy błędu: skrypty operują na wartości zmiennej sprzed wejścia do pętli, co uniemożliwia proste liczenie iteracji.
Natychmiastowe rozszerzanie (parse-time expansion): domyślny mechanizm interpretera cmd.exe polegający na zamianie wszystkich identyfikatorów %ZMIENNA% na ich aktualne wartości tekstowe w momencie parsowania całej linii lub złożonego bloku kodu w nawiasach (...), zanim którakolwiek instrukcja z tego bloku zostanie zinterpretowana i wykonana.
@echo off
setlocal

set LICZNIK=0
echo Przed pętlą, LICZNIK = %LICZNIK%
echo.

echo Próba inkrementacji w pętli FOR:
for /L %%i in (1,1,5) do (
    set /a LICZNIK+=1
    echo Wewnątrz pętli, iteracja %%i. LICZNIK to wciąż: %LICZNIK%
)
echo.

echo Po pętli, LICZNIK = %LICZNIK%

pause
endlocal

:: --- Oczekiwany (ale błędny) wynik ---
:: Przed pętlą, LICZNIK = 0
:: Wewnątrz pętli... LICZNIK to wciąż: 0
:: Wewnątrz pętli... LICZNIK to wciąż: 0
:: ... (zawsze 0)
:: Po pętli, LICZNIK = 0 (lub %LICZNIK%)
11/45
Opóźnione rozszerzanie zmiennych
Slajd przedstawia mechanizm opóźnionego rozszerzania zmiennych oraz notację wykrzykników !VAR! jako rozwiązanie problemu parsowania bloków.

setlocal EnableDelayedExpansion

  • Dyrektywa EnableDelayedExpansion: włącza w interpreterze tryb odraczania ewaluacji zmiennych do momentu faktycznego wykonania wiersza.
  • Składnia wykrzykników (!VAR!): zmienne otoczone znakami wykrzyknika są ewaluowane dynamicznie w każdej iteracji pętli lub bloku.
  • Zastosowanie w pętlach: umożliwia inkrementację liczników, akumulację danych tekstowych i natychmiastowy odczyt zmienionych wartości.
  • Interakcja ze znakami wykrzyknika: w trybie opóźnionego rozszerzania dosłowny znak ! w tekście wymaga ucieczki za pomocą daszka (^^!).
Opóźnione rozszerzanie zmiennych (delayed expansion): tryb pracy interpretera cmd.exe uruchamiany instrukcją setlocal EnableDelayedExpansion, w którym zmienne ujęte w znaki wykrzyknika (!ZMIENNA!) są ewaluowane tuż przed wykonaniem konkretnej instrukcji w czasie wykonania (runtime), a nie podczas wstępnego wczytywania bloku kodu.
@echo off
setlocal EnableDelayedExpansion

set LICZNIK=0
echo Przed pętlą, LICZNIK = %LICZNIK%
echo.

echo Próba inkrementacji w pętli FOR (z opóźnionym rozszerzaniem):
for /L %%i in (1,1,5) do (
    set /a LICZNIK+=1
    echo Wewnątrz pętli, iteracja %%i. LICZNIK to teraz: !LICZNIK!
)
echo.

echo Po pętli, LICZNIK = !LICZNIK!

pause
endlocal

:: --- Poprawny wynik ---
:: Przed pętlą, LICZNIK = 0
:: Wewnątrz pętli... LICZNIK to teraz: 1
:: Wewnątrz pętli... LICZNIK to teraz: 2
:: ...
:: Po pętli, LICZNIK = 5
12/45
Wyrażenia arytmetyczne
Slajd omawia przełącznik arytmetyczny /a polecenia set, obsługiwane operatory matematyczne i bitowe oraz ograniczenia liczb 32-bitowych.

Operacje na liczbach całkowitych (set /a)

  • Przełącznik arytmetyczny /a: nakazuje interpreterowi zinterpretować ciąg znaków po prawej stronie jako matematyczne wyrażenie liczbowe.
  • Obsługiwane operatory: dodawanie (+), odejmowanie (-), mnożenie (*), dzielenie całkowite (/), modulo (%) oraz operacje bitowe (&, |, ^).
  • Format liczb całkowitych: obliczenia wykonywane są wyłącznie na 32-bitowych liczbach całkowitych ze znakiem (od -2147483648 do 2147483647).
  • Brak liczb zmiennoprzecinkowych: cmd.exe nie obsługuje ułamków dziesiętnych ani liczb zmiennoprzecinkowych bez zewnętrznych narzędzi.
Obliczenia arytmetyczne (set /a): wbudowany podsystem ewaluacji matematycznej w cmd.exe przetwarzający 32-bitowe liczby całkowite. W trybie /a nazwy zmiennych nie wymagają ujmowania w znaki procentu, a operacje dzielenia są dzieleniem całkowitym z odrzuceniem części ułamkowej.
@echo off
setlocal

set A=20
set B=7

set /a SUMA = A + B
set /a ILOCZYN = A * B
set /a ILORAZ = A / B
set /a RESZTA = A %% B

echo %A% + %B% = %SUMA%
echo %A% * %B% = %ILOCZYN%
echo %A% / %B% = %ILORAZ% (dzielenie calkowite)
echo Reszta z dzielenia %A% przez %B% to %RESZTA%
echo.

:: Inkrementacja i dekrementacja
set LICZNIK=10
echo Pierwotna wartość: %LICZNIK%
set /a LICZNIK+=1
echo Po inkrementacji: %LICZNIK%
set /a LICZNIK-=5
echo Po dekrementacji o 5: %LICZNIK%
echo.

:: Operacje zlozone
set X=5
set /a WYNIK = (X + 3) * 2 - 10 / 2
echo (5 + 3) * 2 - 10 / 2 = %WYNIK%

pause
endlocal
13/45
Operacje na ciągach znaków: podciągi
Slajd wyjaśnia mechanizm ekstrakcji fragmentów łańcuchów znakowych za pomocą modyfikatorów indeksu i długości w notacji %VAR:~start,len%.

Wycinanie fragmentów tekstu

  • Składnia wycinania: konstrukcja %ZMIENNA:~poczatek,dlugosc% pozwala wyodrębnić określony podciąg tekstowy.
  • Indeksowanie od zera: pierwszy znak w łańcuchu ma indeks 0; podanie wartości ujemnej liczy pozycję od końca ciągu.
  • Pominięcie parametru długości: zapis %ZMIENNA:~poczatek% pobiera wszystkie znaki od zadanej pozycji aż do końca łańcucha.
  • Ujemna długość: podanie ujemnej długości obcina wskazaną liczbę znaków z końca wyodrębnianego podciągu.
Ekstrakcja podciągu (substring): wbudowana operacja manipulacji tekstem w cmd.exe umożliwiająca pobranie fragmentu zmiennej środowiskowej na podstawie zadanego przesunięcia (offset) i opcjonalnej długości bez konieczności wywoływania zewnętrznych programów filtrujących.
@echo off
setlocal EnableDelayedExpansion

set NAZWA_PLIKU=raport_dzienny_2025-10-09.log

echo Pelna nazwa pliku: %NAZWA_PLIKU%
echo Wartość zmiennej: !NAZWA_PLIKU!
echo.

:: Pierwsze 6 znakow ("raport")
set TYP=%NAZWA_PLIKU:~0,6%
echo Pierwsze 6 znakow: %TYP%

:: Fragment daty (10 znakow, od 15.)
set DATA=%NAZWA_PLIKU:~15,10%
echo Fragment daty: %DATA%

:: Ostatnie 4 znaki (rozszerzenie ".log")
set ROZSZ=%NAZWA_PLIKU:~-4%
echo Rozszerzenie: %ROZSZ%

:: Wszystko oprocz rozszerzenia
set BEZ_ROZSZ=%NAZWA_PLIKU:~0,-4%
echo Nazwa bez rozszerzenia: %BEZ_ROZSZ%

pause
endlocal
14/45
Operacje na ciągach znaków: zamiana
Slajd przedstawia składnię zamiany podciągów w zmiennych środowiskowych (%VAR:wzorzec=nowy%) oraz techniki usuwania znaków.

Wyszukiwanie i zamiana tekstu

  • Składnia zamiany: konstrukcja %ZMIENNA:stary=nowy% wyszukuje wszystkie wystąpienia wzorca i zastępuje je nowym tekstem.
  • Niewrażliwość na wielkość liter: wyszukiwanie wzorca w cmd.exe domyślnie ignoruje wielkość liter (operacja case-insensitive).
  • Usuwanie podciągów: pozostawienie pustego ciągu po znaku równości (%ZMIENNA:stary=%) powoduje całkowite usunięcie dopasowanego wzorca.
  • Zamiana prefiksu gwiazdką: użycie wzorca *tekst zastępuje wszystko od początku łańcucha aż do pierwszego dopasowania.
Podstawienie podciągu (string substitution): funkcja manipulacji łańcuchami w cmd.exe przeszukująca treść zmiennej środowiskowej i podmieniająca wszystkie wystąpienia zadanego ciągu znaków na inny ciąg lub usuwająca je z tekstu wynikowego.
@echo off
setlocal EnableDelayedExpansion

set SCIEZKA=C:\Uzytkownicy\Jan\Dokumenty\Projekt X
echo Oryginalna ścieżka: %SCIEZKA%
echo.

:: Zamien spacje na podkreslenia
set NOWA=!SCIEZKA: =_!
echo Po zamianie spacji: !NOWA!

:: Zamien tylko pierwsze 'U' na 'u'
set ZMIENIONA=!SCIEZKA:U=u!
echo Po zamianie pierwszego U: !ZMIENIONA!
echo.

set ZDANIE=To jest test, testowy test.
echo Oryginalne zdanie: !ZDANIE!

:: Zamien pierwsze wystąpienie 'test' na 'przyklad' (od początku)
set NOWE=!ZDANIE:*test=przyklad!
echo Nowe zdanie (pierwsze od początku): !NOWE!

:: Zamien wszystkie 'test' na 'przyklad'
set WSZYSTKIE=!ZDANIE:test=przyklad!
echo Nowe zdanie (wszystkie): !WSZYSTKIE!

:: Usuwanie tekstu
set TEKST=Prefix_Tresc_Suffix
echo.
echo Oryginalny tekst: !TEKST!
echo Bez Prefix_: !TEKST:Prefix_=!
echo Bez _Suffix: !TEKST:_Suffix=!

pause
endlocal
15/45
Instrukcja warunkowa if
Slajd omawia konstrukcję instrukcji warunkowej if, weryfikację istnienia plików (exist), definicji zmiennych (defined) oraz porównania tekstowe.

Podejmowanie decyzji w skrypcie

  • Sprawdzanie istnienia plików (if exist): weryfikuje fizyczną obecność pliku lub katalogu na nośniku pamięci masowej.
  • Sprawdzanie definicji zmiennych (if defined): bada czy wskazana zmienna została zainicjalizowana w środowisku procesu.
  • Porównania ciągów znaków (==): porównuje dwa łańcuchy; przełącznik /i wyłącza rozróżnianie wielkości liter.
  • Zasady składni bloku else: słowo kluczowe else oraz nawiasy zamykające i otwierające muszą bezwzględnie znajdować się w tej samej linii: ) else (.
Instrukcja warunkowa if: instrukcja sterująca przepływem programu w interpreterze cmd.exe, wykonująca określony blok poleceń wyłącznie wtedy, gdy zadany warunek logiczny jest spełniony. Umożliwia testowanie plików, zmiennych, kodów wyjścia oraz wartości numerycznych.
@echo off
setlocal

set /p ODPOWIEDZ=Czy chcesz kontynuowac? (T/N): 

:: Porownanie ciagu (ignoruje wielkosc liter)
if /I "%ODPOWIEDZ%"=="T" (
    echo Wybrano kontynuacje.
) else (
    echo Anulowano operacje.
    goto :koniec
)

:: Sprawdzenie istnienia pliku
set PLIK_KONFIG=C:\Windows\System32\drivers\etc\hosts
echo.
echo Sprawdzam istnienie pliku %PLIK_KONFIG%...

if exist "%PLIK_KONFIG%" (
    echo Plik został znaleziony.
) else (
    echo Błąd: Nie znaleziono pliku!
)

:: Sprawdzenie zmiennej
set MOJA_ZMIENNA=wartość
if defined MOJA_ZMIENNA (
    echo Zmienna jest zdefiniowana.
)

:koniec
pause
endlocal
16/45
Porównania liczbowe i errorlevel
Slajd przedstawia operatory porównań relacyjnych w cmd.exe oraz precyzyjne metody badania kodów wyjścia procesów.

Porównywanie liczb w instrukcji if

  • Operatory relacyjne: porównania numeryczne wymagają operatorów trójliterowych: EQU, NEQ, LSS, LEQ, GTR, GEQ zamiast symboli matematycznych.
  • Automatyczna konwersja liczb: jeśli oba argumenty składają się wyłącznie z cyfr, interpreter traktuje je jak liczby; w przeciwnym razie porównuje leksykalnie.
  • Semantyka if errorlevel N: historyczna konstrukcja sprawdza czy kod wyjścia jest większy bądź równy N, co może maskować błędy wyższe.
  • Precyzyjne sprawdzanie %ERRORLEVEL%: zalecana nowoczesna składnia if %ERRORLEVEL% equ N bada dokładną wartość kodu powrotu.
Operator relacyjny w cmd.exe: słowo kluczowe służące do porównywania dwóch wartości w instrukcji if. Wyróżnia się operatory: EQU (równy), NEQ (różny), LSS (mniejszy), LEQ (mniejszy lub równy), GTR (większy) oraz GEQ (większy lub równy).
@echo off
setlocal

set /p WIEK=Podaj swoj wiek: 

if "%WIEK%"=="" (
    echo Nie podano wieku.
    goto :koniec
)

:: Porownanie liczbowe
if %WIEK% LSS 18 (
    echo Jestes osoba niepelnoletnia.
) else (
    if %WIEK% LSS 65 (
        echo Jestes osoba dorosla.
    ) else (
        echo Jestes emerytem.
    )
)
echo.

:: Sprawdzenie errorlevel
echo Próbuję skopiować nieistniejący plik...
copy C:\nie\istnieje.txt C:\temp > nul 2> nul

if errorlevel 1 (
    echo Wystąpił błąd!
    echo Kod błędu: %ERRORLEVEL%
) else (
    echo Operacja zakończona sukcesem.
)

:koniec
pause
endlocal
17/45
Pętla for /L: iteracja po liczbach
Slajd omawia przełącznik /L pętli for, zasady definiowania zakresów liczbowych oraz specyfikę zmiennych pętli %%i.

Wykonywanie poleceń zadaną liczbę razy

  • Składnia zakresu (start,krok,koniec): przełącznik /L generuje sekwencję liczb od wartości początkowej z zadanym krokiem aż do limitu.
  • Krok ujemny: podanie ujemnej wartości kroku pozwala na iterację wstecz (odliczanie w dół).
  • Podwajanie procentu w skryptach: w plikach wsadowych zmienna pętli musi mieć postać %%i, podczas gdy w konsoli używa się pojedynczego %i.
  • Czułość na wielkość liter: zmienna pętli %%i jest ściśle odróżniana od %%I przez parser interpretera.
Pętla for /L: wariant pętli iteracyjnej for w cmd.exe generujący ciąg arytmetyczny liczb całkowitych w zadanym przedziale. Służy do powtarzania sekwencji poleceń określoną liczbę razy lub iterowania po ponumerowanych zasobach systemowych.
@echo off
setlocal

echo --- Odliczanie od 1 do 5 ---
for /L %%i in (1, 1, 5) do (
    echo Iteracja numer %%i
)
echo.

echo --- Liczby parzyste od 10 do 20 ---
for /L %%j in (10, 2, 20) do (
    echo Liczba parzysta: %%j
)
echo.

echo --- Odliczanie w dol (animacja) ---
for /L %%k in (5, -1, 1) do (
    echo Pozostalo: %%k sekund...
    timeout /t 1 > nul
)
echo Start!
echo.

:: Generowanie plików z numerami
echo --- Generowanie plików ---
for /L %%n in (1, 1, 3) do (
    echo Zawartosc pliku %%n > plik_%%n.txt
    echo Utworzono: plik_%%n.txt
)
dir plik_*.txt /b
del plik_*.txt

pause
endlocal
18/45
Pętla for: iteracja po plikach
Slajd przedstawia podstawowy wariant pętli for do przetwarzania zbiorów plików za pomocą masek wieloznacznych (* i ?).

Przetwarzanie wielu plików naraz

  • Dopasowanie do masek: pętla for %%f in (*.txt) iteruje po wszystkich plikach w bieżącym katalogu spełniających kryteria wzorca.
  • Obsługa wielu wzorców: wewnątrz nawiasu można podać listę rozdzieloną spacjami lub przecinkami: (*.txt *.log *.csv).
  • Przełącznik /D dla katalogów: zastosowanie for /D ogranicza dopasowanie wyłącznie do nazw podkatalogów, pomijając pliki zwykłe.
  • Puste zbiory dopasowań: jeżeli wzorzec nie zawiera symboli wieloznacznych i plik nie istnieje, pętla wykona się jeden raz traktując nazwę dosłownie.
Pętla dopasowania plików (file globbing for): podstawowa konstrukcja pętli for w cmd.exe wyszukująca w systemie plików elementy odpowiadające zadanym maskom nazw i wykonująca określone polecenie dla każdego znalezionego obiektu.
@echo off
setlocal

echo Tworzę pliki tymczasowe...
echo test > file1.tmp
echo test > file2.tmp
echo test > data.log
echo.

echo --- Zmiana rozszerzenia z .tmp na .txt ---
for %%F in (*.tmp) do (
    echo Zmieniam "%%F" na "%%~nF.txt"
    ren "%%F" "%%~nF.txt"
)
echo.

echo --- Informacje o plikach ---
for %%F in (*.txt) do (
    echo ===========================
    echo Nazwa:     %%~nF
    echo Rozszerzenie: %%~xF
    echo Pełna ścieżka: %%~fF
    echo Rozmiar:   %%~zF bajtów
)
echo ===========================

del *.txt *.log > nul
pause
endlocal
19/45
Pętla for /F: przetwarzanie tekstu
Slajd omawia zaawansowany wariant pętli for /F przeznaczony do parsowania wierszy plików tekstowych, łańcuchów oraz wyników komend.

Czytanie plików i wyników poleceń

  • Trzy źródła danych: przetwarzanie zawartości plików tekstowych, literałów znakowych ujętych w cudzysłowy oraz wyników poleceń ujętych w apostrofy ('polecenie').
  • Opcje delims i tokens: delims określa znaki podziału kolumn (domyślnie spacja i tabulator), a tokens wybiera numery kolumn przekazywanych do zmiennych.
  • Alokacja kolejnych liter: wskazanie wielu tokenów (np. tokens=1,2,3) automatycznie przypisuje kolejne kolumny do kolejnych liter alfabetu (%%a, %%b, %%c).
  • Opcje eol i skip: skip=N pomija zadaną liczbę początkowych wierszy (np. nagłówki), a eol=znak ignoruje linie komentarzy.
Pętla for /F (file parsing): najbardziej rozbudowany wariant pętli for w interpreterze cmd.exe, realizujący podział tekstu na tokeny według zadanych separatorów. Umożliwia wierszowe czytanie plików konfiguracyjnych, parsowanie wyjścia narzędzi konsolowych oraz wyodrębnianie konkretnych parametrów.
@echo off
setlocal EnableDelayedExpansion

:: --- Przetwarzanie wyniku polecenia ---
echo --- Lista plików z dir ---
for /f "tokens=*" %%a in ('dir /b *.cmd 2^>nul') do (
    echo Plik: %%a
)
echo.

:: --- Przetwarzanie pliku CSV ---
echo jkowalski,Jan,Kowalski,IT > uzytkownicy.csv
echo anowak,Anna,Nowak,HR >> uzytkownicy.csv
echo mnowicki,Marek,Nowicki,Finanse >> uzytkownicy.csv

echo --- Dane użytkowników z CSV ---
for /f "tokens=1,2,3,4 delims=," %%a in (uzytkownicy.csv) do (
    echo Login: %%a, Imię: %%b, Nazwisko: %%c, Dział: %%d
)
del uzytkownicy.csv
echo.

:: --- Parsowanie ciągu ---
echo --- Parsowanie daty ---
for /f "tokens=1,2,3 delims=/" %%a in ("2025/12/25") do (
    echo Dzień: %%a, Miesiąc: %%b, Rok: %%c
)

pause
endlocal
20/45
Argumenty wiersza poleceń: podstawy
Slajd przedstawia sposób przekazywania argumentów do skryptu wsadowego oraz dostęp do nich za pomocą zmiennych pozycyjnych od %0 do %9.

Parametry przekazywane do skryptu

  • Zmienne pozycyjne %1 do %9: przechowują wartości kolejnych parametrów przekazanych do pliku wsadowego przy wywołaniu.
  • Zmienna specjalna %0: zawiera nazwę lub dokładną ścieżkę uruchomionego pliku skryptu tak, jak została wprowadzona w konsoli.
  • Zmienna zbiorcza %*: reprezentuje wszystkie przekazane argumenty wiersza poleceń w postaci jednego nienaruszonego łańcucha znaków.
  • Białe znaki w argumentach: parametry zawierające spacje muszą być ujmowane przez użytkownika w podwójne cudzysłowy.
Argumenty pozycyjne: zestaw predefiniowanych zmiennych wiersza poleceń (%0-%9) wypełnianych automatycznie przez interpreter cmd.exe w momencie startu skryptu. Odpowiadają kolejnym słowom wpisanym po nazwie pliku wsadowego, rozdzielanym spacjami lub znakami tabulacji.
@echo off
setlocal

echo === Informacje o wywołaniu skryptu ===
echo Nazwa skryptu: %0
echo.
echo Wszystkie argumenty: %*
echo.

if "%1"=="" (
    echo Błąd: Nie podano argumentów!
    echo Użycie: %~n0 [arg1] [arg2] [arg3]
    goto :koniec
)

echo === Poszczegolne argumenty ===
echo Argument 1: %1
echo Argument 2: %2
echo Argument 3: %3
echo Argument 4: %4
echo Argument 5: %5
echo.

echo Pierwszy i drugi razem: %1 %2

:koniec
pause
endlocal

:: Wywolanie przykładowe:
:: moj_skrypt.bat jeden dwa "trzy slowa" cztery
21/45
Argumenty: modyfikatory rozszerzania
Slajd omawia operatory tyldy pozwalające na rozwijanie składowych ścieżek, usuwanie cudzysłowów oraz odczyt metadanych plików z argumentów.

Modyfikatory tyldy dla parametrów

  • Usuwanie cudzysłowów (%~1): zdejmuje otaczające podwójne cudzysłowy z argumentu, umożliwiając bezpieczne łączenie ścieżek.
  • Rozbijanie na składowe (%~d1, %~p1, %~n1, %~x1): umożliwia wyodrębnienie samej litery dysku (d), ścieżki folderu (p), nazwy pliku (n) oraz rozszerzenia (x).
  • Pełna kwalifikowana ścieżka (%~f1): zamienia relatywną ścieżkę argumentu na pełną bezwzględną ścieżkę kanoniczną w systemie plików.
  • Metadane pliku (%~z1, %~t1): zwraca fizyczny rozmiar pliku w bajtach (z) oraz datę i czas ostatniej modyfikacji (t).
Modyfikator tyldy (tilde modifier): specjalny prefiks w języku wsadowym wprowadzany znakiem tyldy po symbolu procentu (np. %~dp1), który instruuje parser do wykonania natychmiastowej transformacji leksykalnej lub odczytania właściwości pliku wskazanego w parametrze.
@echo off
setlocal

if "%1"=="" (
    echo Użycie: %~n0 ^<ścieżka_do_pliku^>
    goto :koniec
)

echo === Analiza argumentu: %1 ===
echo.
echo %1          = %1
echo ~f1         = %~f1
echo ~d1         = %~d1
echo ~p1         = %~p1
echo ~n1         = %~n1
echo ~x1         = %~x1
echo ~z1         = %~z1
echo.
echo ~dp1        = %~dp1
echo ~dpnx1      = %~dpnx1

:koniec
pause
endlocal

:: Wywolanie przykładowe:
:: moj_skrypt.bat "C:\Moje Dokumenty\raport.pdf"
22/45
Obsługa ścieżek w skryptach
Slajd wyjaśnia zasady prawidłowej manipulacji ścieżkami względnymi i bezwzględnymi oraz zastosowanie poleceń pushd i popd.

Praca z katalogami i ścieżkami

  • Ścieżki bezwzględne i względne: ścieżki bezwzględne określają pełną lokalizację od litery dysku, względne zależą od bieżącego katalogu roboczego.
  • Cytowanie spacji w ścieżkach: każda ścieżka zawierająca spacje (np. C:\Program Files) musi być bezwzględnie ujęta w podwójne cudzysłowy.
  • Stos katalogów (pushd i popd): pushd zapamiętuje bieżący katalog na stosie i przechodzi do nowego; popd przywraca poprzednią lokalizację.
  • Obsługa udziałów sieciowych UNC: polecenie pushd potrafi automatycznie zamapować udział sieciowy (\\serwer\zasob) na tymczasową literę dysku.
Zarządzanie stosem katalogów (pushd/popd): para wbudowanych poleceń powłoki cmd.exe implementująca strukturę danych stosu (LIFO) dla katalogów roboczych. Umożliwia bezpieczną tymczasową zmianę lokalizacji wykonywania operacji ze stuprocentową gwarancją powrotu do katalogu wyjściowego.
@echo off
setlocal EnableDelayedExpansion

:: Ustawienie katalogu skryptu jako bieżącego
set "SCRIPT_DIR=%~dp0"
cd /d "%SCRIPT_DIR%"
echo Katalog skryptu: %SCRIPT_DIR%
echo Bieżący katalog: %CD%
echo.

:: Pobieranie argumentu jako ścieżki
set "PLIK=%~1"

if not defined PLIK (
    echo Nie podano ścieżki do pliku.
    goto :koniec
)

:: Sprawdzenie czy plik istnieje
if exist "%PLIK%" (
    echo Plik istnieje: %PLIK%
    echo.
    echo Informacje o pliku:
echo Pełna ścieżka: %~f1
    echo   Katalog:       %~dp1
    echo   Nazwa:         %~n1
    echo   Rozszerzenie:  %~x1
    echo   Rozmiar:       %~z1 bajtów
) else (
    echo Błąd: Plik nie istnieje: %PLIK%
)

:koniec
pause
endlocal
23/45
Zmienna specjalna %~dp0
Slajd przedstawia konstrukcję %~dp0 jako niezawodną metodę ustalania katalogu macierzystego skryptu oraz przestrzega przed błędem podwójnego ukośnika.

Lokalizacja katalogu skryptu

  • Definicja %~dp0: zwraca literę dysku (d) oraz pełną ścieżkę folderu (p), w którym fizycznie zapisany jest wykonywany plik wsadowy (%0).
  • Niezależność od katalogu roboczego: pozwala na bezbłędne odwoływanie się do plików pomocniczych skryptu niezależnie od miejsca jego wywołania.
  • Kończący ukośnik odwrotny: wartość rozwijana przez %~dp0 zawsze kończy się znakiem ukośnika odwrotnego (np. C:\Projekt\).
  • Pułapka podwójnego separatora: zapis %~dp0\plik.txt generuje nieelegancką ścieżkę z dwoma ukośnikami; prawidłowa składnia to %~dp0plik.txt.
Zmienna %~dp0: specjalny modyfikator zerowego parametru wywołania (%0) w cmd.exe, rozwijany do bezwzględnej ścieżki katalogu zawierającego bieżący skrypt wsadowy wraz z literą dysku i kończącym separatorem folderu. Jest to złoty standard lokalizowania zasobów powiązanych ze skryptem.
@echo off
setlocal EnableDelayedExpansion

:: Zapisz informacje o skrypcie
set "SCRIPT_PATH=%~f0"
set "SCRIPT_DIR=%~dp0"
set "SCRIPT_NAME=%~nx0"

echo === Informacje o skrypcie ===
echo Sciezka:    %SCRIPT_PATH%
echo Katalog:    %SCRIPT_DIR%
echo Nazwa:      %SCRIPT_NAME%
echo.

:: Przejdź do katalogu skryptu
cd /d "%SCRIPT_DIR%"
echo Po zmianie - bieżący: %CD%
echo.

:: Szukaj pliku konfiguracyjnego w katalogu skryptu
set "CONFIG_FILE=%SCRIPT_DIR%config.ini"
if exist "%CONFIG_FILE%" (
    echo Znaleziono config: %CONFIG_FILE%
) else (
    echo Brak pliku konfiguracyjnego.
)
echo.

:: Lista plików w katalogu skryptu
echo Pliki w katalogu skryptu:
for %%F in ("%SCRIPT_DIR%*") do (
    if not "%%~nxF"=="%~nx0" (
        echo   %%~nxF
    )
)

pause
endlocal
24/45
Obsługa wielu argumentów: shift
Slajd omawia polecenie shift służące do sekwencyjnego przetwarzania dowolnej liczby argumentów wykraczającej poza limit zmiennych %1-%9.

Przesuwanie parametrów wiersza poleceń

  • Ograniczenie do 9 zmiennych: interpreter cmd.exe pozwala na bezpośredni dostęp do argumentów wyłącznie przez symbole od %1 do %9.
  • Działanie polecenia shift: przesuwa wszystkie argumenty o jedną pozycję w lewo: %2 staje się %1, %3 staje się %2, a dotychczasowy %1 jest tracony.
  • Pętla przetwarzania argumentów: konstrukcja łącząca shift z pętlą warunkową if "%~1"!="" pozwala przetworzyć nieograniczoną listę plików lub opcji.
  • Przełącznik /n: pozwala rozpocząć przesuwanie od określonej pozycji (np. shift /2 zachowuje nienaruszony argument %1).
Polecenie shift: instrukcja wbudowana interpretera cmd.exe zmieniająca pozycje parametrów pozycyjnych wiersza poleceń poprzez ich przesunięcie w dół o jeden lub więcej indeksów. Umożliwia cykliczne odczytywanie parametrów w pętli do momentu wyczerpania listy wejściowej.
@echo off
setlocal EnableDelayedExpansion

echo === Przetwarzanie wszystkich argumentów ===
echo Otrzymane: %*
echo.

:: Metoda 1: Pętla z shift
echo --- Metoda 1: Pętla z shift ---
:loop1
if "%~1"=="" goto :koniec1
echo Argument: %1
shift
goto :loop1
:koniec1
echo.

:: Metoda 2: FOR (wszystkie na raz)
echo --- Metoda 2: FOR ---
for %%A in (%*) do (
    echo Argument: %%A
)
echo.

:: Metoda 3: Z licznikiem
echo --- Metoda 3: Z licznikiem ---
set /a LICZNIK=0
for %%A in (%*) do (
    set /a LICZNIK+=1
    echo Argument !LICZNIK!: %%A
)
echo.
echo Łącznie: !LICZNIK! argumentów

pause
endlocal

:: Wywolanie:
:: moj_skrypt.bat raz dwa trzy cztery piec szesc
25/45
Sterowanie przepływem: etykiety i goto
Slajd przedstawia składnię definiowania etykiet, zasady bezwarunkowego sterowania przepływem instrukcją goto oraz niebezpieczeństwa spaghetti code.

Bezwarunkowe skoki w skrypcie

  • Definiowanie etykiety: dowolna nazwa poprzedzona pojedynczym dwukropkiem (:etykieta) definiuje punkt docelowy skoku w skrypcie.
  • Instrukcja goto: polecenie goto nazwa_etykiety przenosi wskaźnik wykonania interpretera bezpośrednio do wskazanego wiersza.
  • Etykieta specjalna :eof: skok goto :eof (End Of File) powoduje natychmiastowe zakończenie bieżącego skryptu lub powrót z procedury call.
  • Ryzyko kodu spaghetti: nadużywanie goto prowadzi do utraty czytelności logiki programu; zaleca się stosowanie procedur z instrukcją call.
Instrukcja goto: polecenie bezwarunkowego skoku w interpreterze cmd.exe zmieniające sekwencyjny porządek wykonywania wierszy poprzez przeniesienie sterowania do wskazanej etykiety tekstowej wewnątrz bieżącego pliku wsadowego.
@echo off
setlocal

echo Witaj w prostym menu.
echo.
echo 1. Pokaz date
echo 2. Pokaż listę plików
echo 3. Wyjscie
echo.
set /p WYBOR=Wybierz opcje (1, 2 lub 3): 

if "%WYBOR%"=="1" goto :pokaz_date
if "%WYBOR%"=="2" goto :pokaz_pliki
if "%WYBOR%"=="3" goto :koniec
echo Nieznana opcja.
goto :koniec

:pokaz_date
echo.
echo === Aktualna data ===
date /t
goto :koniec

:pokaz_pliki
echo.
echo === Lista plików ===
dir /b
goto :koniec

:koniec
echo.
echo Koniec programu.
pause
endlocal
26/45
Podprogramy z call: tworzenie funkcji
Slajd wyjaśnia mechanizm tworzenia wielokrotnego użytku podprogramów za pomocą wywołania call :etykieta oraz zasady powrotu z procedury.

Modularyzacja kodu skryptu

  • Wywołanie podprogramu (call :etykieta): uruchamia fragment kodu oznaczony etykietą, zapamiętując adres powrotu na stosie wykonawczym.
  • Przekazywanie argumentów: do podprogramu można przekazywać parametry: call :funkcja arg1 arg2, które stają się lokalnymi %1, %2 wewnątrz procedury.
  • Powrót z procedury (exit /b): zakończenie podprogramu instrukcją exit /b lub goto :eof wznawia działanie skryptu tuż za instrukcją call.
  • Bariera głównego kodu: przed pierwszą etykietą funkcyjną należy bezwzględnie umieścić exit /b 0, aby zapobiec samoczynnemu wpadnięciu w kod funkcji.
Podprogram wsadowy (batch subroutine): wydzielony blok instrukcji wewnątrz pliku wsadowego oznaczony etykietą, wywoływany instrukcją call i kończony instrukcją powrotu exit /b. Realizuje koncepcję funkcji proceduralnej, pozwalając na ponowne wykorzystanie kodu i hermetyzację obliczeń.
@echo off
setlocal

echo === Główna część ===
echo Wywołuje podprogram raz pierwszy...
call :wyswietl_info "Pierwszy raz"
echo Wróciłem. Wywołuje raz drugi...
call :wyswietl_info "Drugi raz"
echo Wywołuje funkcję z liczbami...
call :oblicz_sume 10 20
echo Suma: %ERRORLEVEL%

echo Koniec.
pause
goto :eof

:: ============================================
:wyswietl_info
echo.
echo   --- W podprogramie 'wyswietl_info' ---
echo   Czas: %TIME%
echo   Argument: %~1
echo   --- Koniec ---
echo.
goto :eof

:: ============================================
:oblicz_sume
set /a "SUMA=%~1 + %~2"
exit /b %SUMA%
27/45
Podprogramy: zwracanie wartości
Slajd omawia techniki zwracania danych z podprogramów przez kody wyjścia (exit /b) oraz przez zmienne środowiskowe z wykorzystaniem endlocal.

Przekazywanie wyników obliczeń

  • Zwracanie kodów liczbowych: instrukcja exit /b [kod] ustawia wartość zmiennej %ERRORLEVEL% na zadaną liczbę całkowitą.
  • Ograniczenie kodów wyjścia: kody wyjścia pozwalają przekazać wyłącznie jednobajtowe liczby całkowite statusu, a nie złożone łańcuchy tekstu.
  • Zwracanie danych tekstowych: przekazanie nazwy zmiennej wynikowej jako argumentu do funkcji umożliwia dynamiczne przypisanie wartości.
  • Hermetyzacja z setlocal: połączenie lokalnego środowiska z idiomem endlocal & set "%~1=%wynik%" gwarantuje brak zanieczyszczania środowiska.
Przekazywanie wartości przez referencję: zaawansowany wzorzec projektowy w skryptach wsadowych, w którym procedura przyjmuje nazwę zmiennej zewnętrznej jako parametr (np. %1), wykonuje obliczenia w lokalnym bloku setlocal, a na koniec przypisuje wynik bezpośrednio do wskazanej zmiennej w nadrzędnym środowisku.
@echo off
setlocal EnableDelayedExpansion

echo === Demonstracja roznych metod ===

:: Metoda 1: ERRORLEVEL
echo --- Metoda 1: ERRORLEVEL ---
call :get_random
echo Losowa liczba: !ERRORLEVEL!
echo.

:: Metoda 2: Zmienna przez parametr
echo --- Metoda 2: Zmienna ---
set "RESULT="
call :get_timestamp RESULT
echo Znacznik czasu: !RESULT!
echo.

:: Metoda 3: Natychmiastowy set
echo --- Metoda 3: ENDLOCAL trick ---
call :get_uppercase "hello world" RESULT2
echo Tekst wielkimi: !RESULT2!

pause
goto :eof

:: ============================================
:get_random
set /a "RAND=%RANDOM% %% 100"
exit /b !RAND!

:: ============================================
:get_timestamp
setlocal
set "ts=%DATE% %TIME%"
endlocal & set "%~1=%ts%"
goto :eof

:: ============================================
:get_uppercase
setlocal
set "text=%~1"
set "upper=!text:a=A!"
set "upper=!upper:e=E!"
set "upper=!upper:i=I!"
set "upper=!upper:o=O!"
set "upper=!upper:u=U!"
endlocal & set "%~2=%upper%"
goto :eof
28/45
Uruchamianie programów i skryptów
Slajd wyjaśnia różnice pomiędzy wywołaniem bezpośrednim, instrukcją call oraz poleceniem start z przełącznikami asynchronicznymi.

Różne sposoby uruchamiania programów

  • Uruchomienie bezpośrednie: uruchomienie innego pliku wsadowego bez słowa call bezpowrotnie przekazuje sterowanie i nigdy nie wraca do skryptu macierzystego.
  • Uruchomienie przez call: wywołanie zewnętrznego skryptu wsadowego z powrotem po jego zakończeniu.
  • Polecenie start: uruchamia aplikację w osobnym oknie lub równoległym procesie asynchronicznym bez blokowania skryptu głównego.
  • Przełącznik start /wait: uruchamia zewnętrzny proces w osobnym wątku, lecz wstrzymuje bieg skryptu wsadowego aż do jego zamknięcia.
Polecenie start: wbudowane polecenie interpretera cmd.exe służące do uruchamiania programów, otwierania dokumentów w aplikacjach domyślnych lub inicjowania nowych sesji konsoli. Pozwala na asynchroniczne wykonywanie zadań równoległych w systemie Windows.
@echo off
setlocal

echo === Wywolywanie innych programow ===

:: Uruchomienie notatnika (nie czeka)
echo Uruchamiam Notatnik...
start notepad
echo Notatnik uruchomiony (w tle).
echo.

:: Uruchomienie z czekaniem
echo Uruchamiam kalkulator i czekam...
start /wait calc
echo Kalkulator zamkniety.
echo.

:: Wywołanie innego skryptu z argumentami
echo Wywołuje podskrypt z argumentami...
call sub_script.bat "arg1" "arg 2" 123
echo Podskrypt zakonczony.
echo.

:: Przekazanie wszystkich argumentów dalej
echo Przekazuje wszystkie argumenty...
call sub_script2.bat %*

pause
endlocal
29/45
Przekierowanie wejścia-wyjścia
Slajd omawia strumienie wejścia/wyjścia (stdin, stdout, stderr), operatory przekierowań (> , >>, <) oraz urządzenie specjalne NUL.

Czym jest przekierowanie?

  • Strumienie standardowe: podział na strumień wejściowy STDIN (deskryptor 0), wyjściowy STDOUT (1) oraz błędów STDERR (2).
  • Operatory nadpisywania i dopisywania: pojedynczy znak &gt; nadpisuje plik docelowy, podwójny &gt;&gt; dopisuje dane na końcu istniejącego pliku.
  • Przekierowanie błędów (2>&1): konstrukcja 2&gt;&amp;1 scala strumień komunikatów o błędach ze standardowym strumieniem wyjściowym.
  • Urządzenie NUL: wirtualne urządzenie systemowe NUL pochłania wszelkie przekierowane dane, służąc do całkowitego wyciszania poleceń.
Przekierowanie wejścia-wyjścia (I/O Redirection): mechanizm systemu operacyjnego umożliwiający zmianę domyślnego źródła danych wejściowych lub celu strumieni wyjściowych programu z klawiatury i ekranu konsoli na pliki dyskowe, potoki lub urządzenia specjalne.
@echo off
setlocal EnableDelayedExpansion

echo === Przykłady przekierowań ===
echo.

:: Tworzenie pliku z wynikiem dir (nadpisz)
dir /b > lista_plikow.txt
echo Utworzono plik lista_plikow.txt

:: Dopisanie daty do istniejacego pliku
echo. >> lista_plikow.txt
echo --- Data utworzenia --- >> lista_plikow.txt
date /t >> lista_plikow.txt

:: Wyswietlenie zawartosci pliku
echo.
echo Zawartosc pliku:
type lista_plikow.txt
echo.

:: Wczytanie pierwszej linii do zmiennej
set /p WCZYTANA=<lista_plikow.txt
echo Pierwsza linia pliku: !WCZYTANA!

:: Ukrycie błędów - sprawdz nieistniejący plik
echo.
echo Sprawdzam nieistniejący plik...
copy C:\nie_ma\takiego.txt C:\temp > nul 2> nul
echo Operacja zakończona (błędy ukryte).

:: Pokazanie błędów
echo.
echo Teraz te same z błędami:
copy C:\nie_ma\takiego.txt C:\temp 2>&1

del lista_plikow.txt
pause
endlocal
30/45
Potoki i łączenie poleceń
Slajd wyjaśnia architekturę potoków danych w cmd.exe, operatory logiczne łączenia poleceń (&&, ||) oraz filtry find i sort.

Potoki (pipes)

  • Mechanizm potoku (|): przekazuje strumień wyjściowy STDOUT pierwszego programu bezpośrednio na wejście STDIN drugiego programu.
  • Standardowe filtry: narzędzia find i findstr do przeszukiwania wzorców tekstowych, sort do sortowania wierszy oraz more do stronicowania.
  • Operator warunkowy &&: wykonuje drugie polecenie tylko wtedy, gdy pierwsze zakończyło się pełnym sukcesem (ERRORLEVEL 0).
  • Operator alternatywy ||: wykonuje drugie polecenie tylko wtedy, gdy pierwsze zakończyło się błędem (ERRORLEVEL różny od 0).
Potok systemowy (pipe): jednokierunkowy kanał komunikacji międzyprocesowej (IPC) zarządzany przez jądro systemu, łączący wyjście jednego procesu z wejściem drugiego bez konieczności tworzenia pośrednich plików tymczasowych na dysku.
@echo off
setlocal

echo === Przykłady potoków ===
echo.

:: Sortowanie wyników dir
echo Sortowane pliki *.cmd:
dir /b *.cmd 2>nul | sort

echo.
:: Zliczanie plików
echo Liczba plików .cmd:
dir /b *.cmd 2>nul | find /c /v ""

echo.
echo === Przykłady łączenia poleceń ===
echo.

:: && - wykonaj tylko gdy sukces
echo Sprawdzam istniejący plik:
type %~n0.cmd >nul 2>&1 && echo ISTNIEJE

:: || - wykonaj tylko gdy wystąpi błąd
echo.
echo Sprawdzam nieistniejący plik:
type nie_ma.txt >nul 2>&1 || echo NIE ISTNIEJE (oczekiwane)

:: & - wykonaj oba
echo.
echo Użycie &: Polecenie 1 & Polecenie 2
echo Wyświetlam numer & echo Wersja: 1.0

pause
endlocal
31/45
Obsługa błędów i kody powrotu
Slajd omawia konwencję kodów wyjścia %ERRORLEVEL%, metody ich przechwytywania oraz zasady rygorystycznej obsługi błędów w skryptach.

Kody powrotu (exit codes)

  • Konwencja kodów wyjścia: wartość 0 oznacza pomyślne wykonanie polecenia, wartości dodatnie (zwykle 1-255) sygnalizują specyficzne błędy.
  • Zmienna %ERRORLEVEL%: automatycznie aktualizowana przez system po zakończeniu każdego programu zewnętrznego.
  • Zgłaszanie błędów przez exit /b: zakończenie skryptu z jawnym kodem błędu (np. exit /b 1) informuje systemy nadrzędne o niepowodzeniu.
  • Weryfikacja natychmiastowa: sprawdzanie statusu operacji krytycznych (np. kopiowania czy pobierania danych) przed przejściem do kolejnych kroków.
Kod wyjścia (exit code / errorlevel): liczba całkowita zwracana przez proces do systemu operacyjnego w momencie zakończenia działania. Służy do zwięzłego zakomunikowania procesowi nadrzędnemu sukcesu operacji lub rodzaju napotkanego błędu wykonawczego.
@echo off
setlocal EnableDelayedExpansion

echo === Obsługa błędów ===

set "BLEDNY_PLIK=C:\nie_istnieje.txt"

echo --- Próba 1: Plik nie istnieje ---
copy "%BLEDNY_PLIK%" C:\temp >nul 2>&1
if errorlevel 1 (
    echo BŁĄD: Plik nie istnieje!
) else (
    echo SUKCES: Plik skopiowany.
)
echo.

echo --- Próba 2: z || ---
copy "%BLEDNY_PLIK%" C:\temp >nul && echo SUKCES || echo BŁĄD (oczekiwane)

echo.
echo --- Próba 3: z && ---
copy %~n0.cmd nul >nul && echo PLIK ISTNIEJE || echo BŁĄD

pause
endlocal
32/45
Pętla for /R: rekursywne przeszukiwanie
Slajd przedstawia przełącznik /R pętli for, zasady rekursywnego przeszukiwania drzewa katalogów oraz operacje na odnalezionych plikach.

Rekursywne przechodzenie przez katalogi

  • Przełącznik rekursji /R: nakazuje pętli for przeszukać bieżący folder oraz wszystkie zagnieżdżone podkatalogi w głąb drzewa dyskowego.
  • Wskazanie katalogu bazowego: składnia for /R "katalog_startowy" %%f in (*.ext) pozwala rozpocząć przeszukiwanie od dowolnego folderu.
  • Zmienna jako pełna ścieżka: zmienna pętli otrzymuje bezwzględną, pełną ścieżkę do każdego odnalezionego pliku.
  • Pojedyncza kropka jako maska: zastosowanie for /R %%d in (.) iteruje po wszystkich węzłach struktury folderów bez listowania plików.
Rekursja w systemie plików (for /R): mechanizm automatycznego trawersowania hierarchicznej struktury katalogów w głąb, polegający na sekwencyjnym odwiedzaniu folderu bazowego oraz wszystkich jego potomków na dowolnym poziomie zagnieżdżenia.
@echo off
setlocal EnableDelayedExpansion

set "START_DIR=%CD%"
set /a LICZNIK=0

echo === Rekurencyjne przechodzenie ===
echo Szukam plików .txt w %START_DIR%...
echo.

for /R "%START_DIR%" %%F in (*.txt) do (
    set /a LICZNIK+=1
    echo !LICZNIK!: %%~nxF
    echo       Sciezka: %%~dpF
)
echo.

echo Znaleziono !LICZNIK! plików .txt
echo.

:: Wyszukiwanie plików konfiguracyjnych
echo === Pliki konfiguracyjne ===
for /R "%START_DIR%" %%F in ("*.ini" "*.cfg" "*.conf") do (
    echo Znaleziono: %%~nxF
)

pause
endlocal
33/45
Pseudo-tablice w skryptach CMD
Slajd wyjaśnia metody emulacji struktur tablicowych w cmd.exe za pomocą zmiennych indeksowanych oraz opóźnionego rozszerzania.

Brak natywnych tablic w CMD

  • Brak natywnych tablic: język wsadowy cmd.exe nie posiada wbudowanego typu danych tablicowych ani indeksowanych struktur danych.
  • Emulacja zmiennymi ze wskaźnikiem: tablice tworzy się przez dynamiczne nazwy zmiennych, np. element_1, element_2, przechowując ich rozmiar w zmiennej count.
  • Zapis z opóźnionym rozszerzaniem: wypełnianie pseudo-tablicy w pętli wymaga składni set "tablica_!i!=wartosc" przy włączonym EnableDelayedExpansion.
  • Odczyt z podwójnym podstawieniem: odczytanie elementu o dynamicznym indeksie i wymaga zapisu !tablica_%i%! lub wywołania pomocniczego call.
Pseudo-tablica w cmd.exe: wzorzec programistyczny symulujący tablicę jedno- lub wielowymiarową w języku wsadowym poprzez grupę standardowych zmiennych środowiskowych o wspólnej nazwie bazowej i numerycznym sufiksie identyfikującym indeks elementu.
@echo off
setlocal EnableDelayedExpansion

echo === Symulacja tablic ===
echo.

:: Definiowanie "tablicy" uzytkownikow
set "USER[0]=Jan Kowalski"
set "USER[1]=Anna Nowak"
set "USER[2]=Piotr Wisniewski"
set "USER[3]=Katarzyna Wozniak"
set "COUNT=4"

echo --- Wyswietlanie ---
for /L %%i in (0,1,3) do (
    echo Element %%i: !USER[%%i]!
)
echo.

echo --- Wyszukiwanie ---
set "SZUKANY=Anna Nowak"
for /L %%i in (0,1,3) do (
    if "!USER[%%i]!"=="%SZUKANY%" (
        echo Znalazlem: !USER[%%i]! na pozycji %%i
    )
)
echo.

echo --- Zmiana elementu ---
set "USER[1]=Anna Maria Nowak"
echo Zmieniony element 1: !USER[1]!

pause
endlocal
34/45
Zmienne środowiskowe i setx
Slajd przedstawia różnice pomiędzy ulotnymi zmiennymi procesu (set) a trwałymi zmiennymi systemowymi i użytkownika modyfikowanymi poleceniem setx.

Zmienne środowiskowe w Windows

  • Ulotność polecenia set: zmienne zdefiniowane za pomocą set istnieją wyłącznie w pamięci bieżącego procesu cmd.exe i znikają po jego zamknięciu.
  • Trwałość polecenia setx: narzędzie setx zapisuje zmienne na stałe w rejestrze systemowym Windows, czyniąc je dostępnymi dla wszystkich przyszłych sesji.
  • Zasięg użytkownika i maszyny: setx domyślnie modyfikuje rejestr bieżącego użytkownika; przełącznik /M zapisuje zmienną globalną dla całego komputera.
  • Brak natychmiastowego odświeżenia: zmienna ustawiona przez setx nie staje się automatycznie dostępna w oknie konsoli, z którego wywołano polecenie.
Polecenie setx: zewnętrzne narzędzie administracyjne systemu Windows służące do tworzenia i modyfikowania trwałych zmiennych środowiskowych w rejestrze systemowym (HKCU lub HKLM) bez konieczności otwierania graficznego apletu właściwości systemu.
@echo off
setlocal

echo === Praca ze zmiennymi srodowiskowymi ===
echo.

:: Wyswietlenie wybranych zmiennych
echo Zmienna USERNAME: %USERNAME%
echo Zmienna COMPUTERNAME: %COMPUTERNAME%
echo Zmienna USERPROFILE: %USERPROFILE%
echo.

:: Ustawienie tymczasowe (tylko sesja)
set MOJA_ZMIENNA=TestowaWartosc
echo Ustawilem MOJA_ZMIENNA=%MOJA_ZMIENNA%

:: Odczyt z rejestru (trwale zmienne User)
echo.
echo Zmienna PATH (User) z rejestru:
reg query "HKCU\Environment" /v PATH 2>nul

:: setx - ODKOMENTUJ JESLI CHCESZ UZYC
:: setx MOJA_ZMIENNA "NowaWartosc"
:: Ustawienie systemowe (wymaga admina):
:: setx MOJA_ZMIENNA "NowaWartosc" /M

echo.
echo UWAGA: setx ustawia trwale ale nie wplywa na biezaca sesje.

pause
endlocal
35/45
Polecenia sterujące: timeout, choice, color
Slajd omawia narzędzia interaktywne wiersza poleceń: odmierzanie czasu (timeout), menu wyboru (choice) oraz estetykę konsoli (color i title).

Interakcja i sterowanie konsolą

  • Polecenie timeout: wstrzymuje wykonywanie skryptu na określoną liczbę sekund; przełącznik /nobreak ignoruje naciśnięcia klawiszy poza Ctrl+C.
  • Polecenie choice: prezentuje użytkownikowi listę dozwolonych klawiszy wyboru i ustawia %ERRORLEVEL% na numer wybranej opcji.
  • Polecenie color: zmienia kolory tła i tekstu okna terminala za pomocą dwucyfrowego kodu szesnastkowego.
  • Polecenie title: ustawia czytelny tekst na pasku tytułowym okna wiersza poleceń informujący o stanie procesu.
Polecenie choice: wbudowane narzędzie konsoli Windows służące do pobierania pojedynczego znaku wyboru od użytkownika z predefiniowanego zestawu klawiszy. Eliminuje konieczność naciskania klawisza Enter i w bezpieczny sposób zwraca indeks wybranej opcji przez kod powrotu.
@echo off
setlocal

title Demonstracja polecen sterujacych

:: Zmiana kolorow
color 17
echo Kolor niebieski na bialym
timeout /t 2 > nul
color 07
echo Powrot do zwyklych kolorow.
echo.

:: timeout z czekaniem
echo Za chwile nastapi odliczanie...
timeout /t 5 /nobreak
echo Czas minal!
echo.

:: choice - interaktywne menu
echo Wybierz opcje:
choice /c TNP /m "T-tak, N-nie, P-pomoc"

if %ERRORLEVEL% equ 1 (
    echo Wybrano: T - kontynuuj!
) else if %ERRORLEVEL% equ 2 (
    echo Wybrano: N - anulowano.
) else (
    echo Wybrano: P - wyświetlam pomoc...
)

pause
endlocal
36/45
Operacje na plikach i katalogach
Slajd przedstawia podstawowe polecenia do zarządzania plikami i katalogami: copy, xcopy, robocopy, move, del, md oraz rd.

Podstawowe polecenia systemowe

  • Tworzenie i usuwanie folderów (md / rd): md tworzy całą ścieżkę zagnieżdżonych katalogów; rd /s /q bezwzględnie usuwa folder wraz z całą zawartością.
  • Kopiowanie i przenoszenie (copy / move): copy służy do prostego kopiowania plików, move przenosi pliki lub zmienia nazwy całych katalogów.
  • Usuwanie plików (del): del usuwa wybrane pliki; przełącznik /f wymusza usunięcie plików tylko do odczytu, a /q wyłącza potwierdzenia.
  • Przewaga narzędzia robocopy: robocopy (Robust File Copy) to przemysłowe narzędzie z obsługą wznawiania przerwanych transferów i lustrzanej synchronizacji (/MIR).
Robocopy (Robust File Copy): zaawansowane systemowe narzędzie wiersza poleceń do replikacji danych dyskowych w systemach Windows. Zapewnia wysoką odporność na przerwy w transmisji sieciowej, zachowuje wszystkie atrybuty i uprawnienia NTFS (ACL) oraz wspiera kopiowanie wielowątkowe.
@echo off
setlocal EnableDelayedExpansion

:: Tworzenie struktury katalogów
echo Tworzę tymczasową strukturę...
mkdir "test_dir" 2>nul
mkdir "test_dir\subdir1" 2>nul
mkdir "test_dir\subdir2" 2>nul
echo.

:: Tworzenie plików testowych
echo Tworzę pliki...
echo Zawartosc pliku 1 > "test_dir\plik1.txt"
echo Zawartosc pliku 2 > "test_dir\plik2.txt"
echo Zawartosc pliku 3 > "test_dir\subdir1\plik3.txt"
echo.

:: Kopiowanie
echo Kopiowanie *.txt do subdir2...
copy "test_dir\*.txt" "test_dir\subdir2\" > nul

:: Lista plików
echo Pliki w test_dir\subdir2:
for %%F in ("test_dir\subdir2\*") do (
    echo   %%~nxF
)
echo.

:: Usuwanie calej struktury
echo Usuwam strukture...
rmdir /s /q "test_dir"
echo Usunięto.

pause
endlocal
37/45
Debugowanie skryptów CMD
Slajd omawia strategie debugowania skryptów wsadowych: włączanie echa (@echo on), krokową inspekcję zmiennych oraz analizę składniową.

Techniki diagnozowania i usuwania błędów

  • Włączenie echa (@echo on): wyświetla każdą interpretowaną linię przed jej wykonaniem, ujawniając stan po rozwinięciu zmiennych.
  • Krokowa inspekcja z poleceniem pause: umieszczenie punktów wstrzymania pozwala na bieżąco kontrolować stan plików na dysku i wartości zmiennych.
  • Wyświetlanie stanu zmiennych: weryfikacja zawartości zmiennych przez celowe wypisywanie komunikatów diagnostycznych: echo DEBUG: [!zmienna!].
  • Test syntaktyczny cmd /c /v:on: uruchomienie skryptu w nowej powłoce z jawnym włączeniem logowania ułatwia diagnozę błędów w pętlach.
Debugowanie skryptu wsadowego: systematyczny proces analizy działania kodu pliku wsadowego mający na celu wykrycie i eliminację błędów logicznych, składniowych oraz nieoczekiwanych zachowań interpretera powłoki cmd.exe podczas przetwarzania danych.
@echo off
setlocal EnableDelayedExpansion

:: Wlacz/wylacz debugowanie
set "DEBUG=1"
:: DEBUG=0 - wylaczone

goto :start

:debug
if %DEBUG% equ 1 (
    echo [DEBUG] %~1
)
goto :eof

:start
call :debug "Rozpoczynam skrypt"
echo.

set "TEST_VAR=wartosc_testowa"
call :debug "TEST_VAR = !TEST_VAR!"
echo.

call :debug "Sprawdzam ERRORLEVEL..."
call :debug "ERRORLEVEL = !ERRORLEVEL!"

if %DEBUG% equ 1 (
    echo.
    echo ==========================
    echo Stan zmiennych:
    echo DEBUG = !DEBUG!
    echo TEST_VAR = !TEST_VAR!
    echo ==========================
)

pause
endlocal
38/45
Bezpieczeństwo skryptów: dobre praktyki
Slajd przedstawia reguły tworzenia bezpiecznych skryptów wsadowych: unikanie wstrzykiwania poleceń, cytowanie ścieżek i kontrolę uprawnień.

Zasady bezpiecznego pisania skryptów

  • Cytowanie wszystkich ścieżek: każda zmienna reprezentująca ścieżkę lub ciąg wprowadzony z zewnątrz musi być ujęta w podwójne cudzysłowy.
  • Ochrona przed command injection: nieostrożne użycie znaków specjalnych (&, |, <, >) we wprowadzanych danych może doprowadzić do wykonania wrogich poleceń.
  • Weryfikacja uprawnień administracyjnych: sprawdzenie czy skrypt posiada niezbędne prawa przed rozpoczęciem modyfikacji kluczowych plików systemowych.
  • Jawne definiowanie katalogu roboczego: rozpoczynanie skryptu od cd /d "%~dp0" zabezpiecza przed operacjami na niewłaściwych katalogach.
Wstrzykiwanie poleceń (command injection): podatność bezpieczeństwa w skryptach polegająca na przekazaniu nieprzefiltrowanych danych wejściowych zawierających operatory łączenia poleceń (np. & lub |), co powoduje zinterpretowanie fragmentu danych jako samodzielnego polecenia powłoki systemowej.
@echo off
setlocal

set "SCRIPT_NAME=%~nx0"
set "ERRORS=0"

:: 1. Sprawdzenie argumentów
if "%~1"=="" (
    echo Błąd: Brak argumentów.
    set /a ERRORS+=1
    goto :show_usage
)

:: 2. Sprawdzenie czy plik istnieje
if not exist "%~1" (
    echo Błąd: Plik nie istnieje.
    set /a ERRORS+=1
    goto :cleanup
)

:: 3. Walidacja ścieżki (brak ..)
echo %~f1 | findstr /C:".." > nul
if not errorlevel 1 (
    echo Błąd: Nieprawidłowa ścieżka.
    set /a ERRORS+=1
    goto :cleanup
)

set "SAFE_FILE=%~nx1"
echo Przetwarzanie: %SAFE_FILE%

:: 4. Obsługa błędów
copy "%SAFE_FILE%" "backup_%SAFE_FILE%" > nul 2>&1
if errorlevel 1 (
    echo Błąd podczas kopiowania.
    set /a ERRORS+=1
)

:cleanup
echo.
if %ERRORS% equ 0 (
    echo Status: SUKCES
) else (
    echo Status: BŁĘDY (%ERRORS%)
    exit /b 1
)

:show_usage
echo Użycie: %SCRIPT_NAME% ^<plik^>

endlocal
39/45
Praktyczny przykład: generator logów
Slajd demonstruje implementację podprogramu rejestracji zdarzeń ze znacznikami czasu i poziomami istotności.

System logowania dla skryptów

  • Format wpisu do dziennika: każdy wiersz logu powinien zawierać precyzyjną datę, czas, poziom istotności (INFO/WARN/ERROR) oraz treść komunikatu.
  • Jednoczesne logowanie i wyświetlanie: zapis do pliku dziennika (&gt;&gt;logfile) połączony z wyświetlaniem na ekranie konsoli.
  • Dedykowany podprogram logujący: zamknięcie logiki zapisu w procedurze call :log pozwala na zachowanie jednolitego formatu w całym skrypcie.
  • Rotacja plików dziennika: tworzenie nowego pliku logu na każdy dzień lub uruchomienie z automatycznym znacznikiem daty w nazwie.
Dziennik zdarzeń skryptu (script log): strukturalny plik tekstowy, w którym skrypt wsadowy chronologicznie rejestruje postęp wykonywania operacji, parametry wejściowe, ostrzeżenia oraz błędy wykonawcze w celu późniejszego audytu i monitoringu.
@echo off
setlocal EnableDelayedExpansion

:: ============================================
:: SYSTEM LOGOWANIA
:: ============================================
set "LOG_FILE="
set "LOG_TO_FILE=0"
set "LOG_TO_SCREEN=1"

:init_log
set "LOG_FILE=%~1"
if defined LOG_FILE set "LOG_TO_FILE=1"
goto :eof

:log
set "TIMESTAMP=%DATE% %TIME%"
if !LOG_TO_SCREEN! equ 1 (
    echo !TIMESTAMP! %~1 %~2
)
if !LOG_TO_FILE! equ 1 (
    echo !TIMESTAMP! %~1 %~2 >> "!LOG_FILE!"
)
goto :eof

:: ============================================
:: UŻYCIE SYSTEMU LOGOWANIA
:: ============================================

call :init_log "moj_log.txt"

call :log "[INFO]" "Rozpoczynam skrypt"
call :log "[INFO]" "Wykonywanie operacji..."

set /a TEST=10/2
call :log "[INFO]" "Wynik: !TEST!"

call :log "[ERROR]" "Nie udalo sie wykonac operacji!"

call :log "[INFO]" "Koniec skryptu"

echo.
echo Log zapisany do: moj_log.txt
type moj_log.txt

pause
endlocal
40/45
Projekt: skrypt backup z datą
Slajd prezentuje kompleksowy projekt skryptu tworzącego kopię zapasową wskazanych folderów z generowaniem unikalnej nazwy ze stemplem czasu.

Kopia zapasowa z automatycznym znacznikiem czasu

  • Pobranie znacznika czasu: wygenerowanie unikalnego ciągu daty i godziny w formacie RRRRMMDD_GGMMSS do nazwy folderu docelowego.
  • Użycie polecenia robocopy: replikacja danych z lustrzanym zachowaniem uprawnień i pomijaniem zablokowanych plików tymczasowych.
  • Weryfikacja kodów wyjścia robocopy: robocopy traktuje kody 0-7 jako sukces (różne stany plików skopiowanych), a kody &gt;= 8 jako błędy krytyczne.
  • Rejestracja w dzienniku zdarzeń: pełne logowanie parametrów startowych, czasu trwania oraz rozmiaru zabezpieczonych danych.
Kopia zapasowa (backup): proces tworzenia duplikatu newralgicznych zasobów dyskowych w odrębnej lokalizacji fizycznej lub sieciowej w celu zapewnienia ciągłości działania i możliwości odtworzenia danych w razie awarii sprzętu lub błędu ludzkiego.
@echo off
setlocal EnableDelayedExpansion

set "SCRIPT_NAME=%~nx0"
set "DEFAULT_BACKUP=%USERPROFILE%\Documents\Backup"

:: --- Walidacja argumentów ---
if "%~1"=="" (
    echo Błąd: Nie podano źródła!
    echo Użycie: %SCRIPT_NAME% ^<plik_lub_katalog^> [cel]
    exit /b 1
)

set "SOURCE=%~f1"
if not exist "%SOURCE%" (
    echo Błąd: Źródło nie istnieje!
    exit /b 1
)

set "DEST=%~f2"
if "%~2"=="" set "DEST=%DEFAULT_BACKUP%"

:: --- Generowanie znacznika czasu ---
set "TS=%DATE:~-4%%DATE:~-7,2%%DATE:~-10,2%"
set "TS=%TS%_%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%"
set "TS=!TS: =0!"

:: --- Tworzenie kopii ---
set "BACKUP_NAME=%~n1_backup_%TS%%~x1"
set "BACKUP_PATH=%DEST%\%BACKUP_NAME%"

echo Tworzę kopię zapasową...
echo Źródło: %SOURCE%
echo Cel: %BACKUP_PATH%

if exist "%SOURCE%\*" (
    mkdir "!DEST!" 2>nul
    xcopy /e /i /h /y "%SOURCE%" "!BACKUP_PATH!\" > nul 2>&1
) else (
    mkdir "!DEST!" 2>nul
    copy /y "%SOURCE%" "!BACKUP_PATH!" > nul 2>&1
)

if !ERRORLEVEL! equ 0 (
    echo SUKCES: Kopia utworzona!
) else (
    echo BŁĄD: Nie udało się utworzyć kopii.
    exit /b 1
)

endlocal
41/45
Projekt: menu instalacyjne
Slajd przedstawia konstrukcję modułowego skryptu instalacyjnego wyposażonego w menu interaktywne, badanie uprawnień i rejestrację składników.

Skrypt instalacyjny z menu wyboru

  • Badanie uprawnień UAC: wywołanie polecenia net session weryfikuje czy instalator został uruchomiony z prawami administratora.
  • Interaktywny interfejs: zbudowanie czytelnego menu tekstowego opartego na narzędziu choice lub etykietach i komendzie set /p.
  • Modułowa instalacja pakietów: wywoływanie autonomicznych funkcji instalacyjnych odpowiedzialnych za kopiowanie binariów i konfigurację usług.
  • Obsługa wycofania zmian (rollback): przywrócenie stanu pierwotnego w przypadku niepowodzenia instalacji któregoś z komponentów.
Skrypt wdrożeniowy (installer script): wyspecjalizowany program wsadowy automatyzujący proces instalacji, konfiguracji oraz integracji aplikacji w systemie operacyjnym bez konieczności manualnej ingerencji administratora w pliki konfiguracyjne.
@echo off
setlocal EnableDelayedExpansion

set "APP_NAME=MojaAplikacja"
set "APP_VERSION=1.0.0"

:: Sprawdzenie uprawnien admina
net session >nul 2>&1
if %errorlevel% neq 0 (
    echo.
    echo UWAGA: Ten skrypt wymaga uprawnien admina!
    echo Kliknij prawym i wybierz "Uruchom jako admin"
    pause
    exit /b 1
)

echo.
echo ============================================
echo   INSTALATOR: %APP_NAME% v%APP_VERSION%
echo ============================================
echo.

set /p INSTALL_DIR="Katalog instalacji (domyslnie C:\%APP_NAME%): "
if not defined INSTALL_DIR set "INSTALL_DIR=C:\%APP_NAME%"

echo.
echo Tworzę katalogi...
mkdir "%INSTALL_DIR%" 2>nul
mkdir "%INSTALL_DIR%\config" 2>nul
mkdir "%INSTALL_DIR%\logs" 2>nul
mkdir "%INSTALL_DIR%\data" 2>nul
echo Katalogi utworzone.

echo.
echo Tworzę plik konfiguracyjny...
echo # Konfiguracja > "%INSTALL_DIR%\config\ustawienia.ini"
echo [app] >> "%INSTALL_DIR%\config\ustawienia.ini"
echo version=%APP_VERSION% >> "%INSTALL_DIR%\config\ustawienia.ini"
echo.

echo === INSTALACJA ZAKONCZONA ===
echo.
echo Zainstalowano w: %INSTALL_DIR%
echo.

pause
endlocal
42/45
Zaawansowane operacje na plikach
Slajd omawia narzędzia forfiles i attrib, zaawansowane filtry czasowe oraz zarządzanie atrybutami plików w wierszu poleceń.

Przeszukiwanie i atrybuty plików

  • Narzędzie forfiles: pozwala na masowe wykonywanie poleceń na plikach spełniających kryteria daty modyfikacji (przełącznik /D).
  • Automatyczne usuwanie starych kopii: komenda forfiles /p ścieżka /s /m *.log /d -30 /c "cmd /c del @path" usuwa pliki starsze niż 30 dni.
  • Polecenie attrib: wyświetla i modyfikuje atrybuty plików: tylko do odczytu (R), ukryty (H), systemowy (S) oraz archiwalny (A).
  • Obsługa uprawnień icacls: modyfikowanie i tworzenie kopii zapasowych list kontroli dostępu NTFS do chronionych folderów.
Polecenie forfiles: zaawansowane systemowe narzędzie wiersza poleceń Windows dedykowane do selekcji plików na podstawie wzorca nazwy, lokalizacji oraz daty ostatniej modyfikacji, umożliwiające automatyczne wywołanie zadanego polecenia dla każdego wyselekcjonowanego obiektu.
@echo off
setlocal EnableDelayedExpansion

set "START_DIR=%CD%"
set /a PLIKOW=0
set /a SUMA_ROZMIAR=0

echo === Analiza katalogów ===
echo Szukam wszystkich plików w %START_DIR%...
echo.

for /R "%START_DIR%" %%F in (*) do (
    set /a PLIKOW+=1
    set /a SUMA_ROZMIAR+=%%~zF
    :: Wyswietl tylko pliki wieksze niz 1MB
    if %%~zF GTR 1048576 (
        echo Duży plik: %%~nxF (%%~zF bajtów)
    )
)

echo.
echo ============================================
echo Podsumowanie:
echo Liczba plików: !PLIKOW!
echo Suma rozmiarow: !SUMA_ROZMIAR!
if !PLIKOW! gtr 0 (
    set /a SREDNI=SUMA_ROZMIAR/PLIKOW
    echo Średni rozmiar: !SREDNI! bajtów
)
echo ============================================

pause
endlocal
43/45
Zaawansowane: praca z datą i czasem
Slajd wyjaśnia problem zależności formatu daty od ustawień regionalnych oraz prezentuje niezawodne metody pobierania stempla czasu przez WMIC i PowerShell.

Manipulacja datą i znaczniki czasu

  • Niestabilność zmiennej %DATE%: kolejność dni, miesięcy i separatorów w %DATE% zależy od ustawień językowych systemu (DD.MM.RRRR vs RRRR-MM-DD vs MM/DD/YYYY).
  • Błąd parsowania na obcych systemach: sztywne wycinanie podciągów %date:~-4% zawodzi po uruchomieniu skryptu na serwerze z angielskim lub niemieckim profilem językowym.
  • Uniwersalne zapytanie WMIC: polecenie wmic os get localdatetime zwraca znormalizowany stempel czasu w standardzie ISO (RRRRMMDDGGMMSS).
  • Jednolinijkowiec PowerShell: nowoczesna alternatywa wywołująca Get-Date -Format 'yyyyMMdd_HHmmss' z poziomu skryptu wsadowego.
Znacznik czasu ISO 8601: międzynarodowy standard zapisu daty i czasu w porządku malejącym (od roku przez miesiąc, dzień, godzinę do sekund), gwarantujący poprawne sortowanie alfabetyczne i chronologiczne plików bez względu na regionalne ustawienia językowe systemu.
@echo off
setlocal EnableDelayedExpansion

echo === Analiza daty i czasu ===
echo.

echo Systemowa data: %DATE%
echo Systemowy czas: %TIME%
echo.

:: Parsowanie daty (format: 2025-03-21)
:: UWAGA: format moze byc inny w zaleznosci od ustawien!
set "D=%DATE%"
echo Próbne parsowanie: !D!

:: Sprobuj wyciagnac rok, miesiac, dzien
:: To zalezy od formatu systemowego!
set "ROK=%DATE:~0,4%"
set "MIESIAC=%DATE:~5,2%"
set "DZIEN=%DATE:~8,2%"
echo Wydzielone: !ROK!-!MIESIAC!-!DZIEN!
echo.

:: Parsowanie czasu
set "GODZ=%TIME:~0,2%"
set "MIN=%TIME:~3,2%"
set "SEK=%TIME:~6,2%"
echo Czas: !GODZ!:!MIN!:!SEK!
echo.

:: Znacznik czasu do nazwy pliku (bez spacji)
set "TS=%DATE:~-4%%DATE:~-7,2%%DATE:~-10,2%_%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%"
set "TS=!TS: =0!"
echo Znacznik do nazwy pliku: !TS!

pause
endlocal
44/45
Porównanie CMD z PowerShell i Bash
Slajd zestawia cechy architektoniczne, zalety, wady oraz zakres optymalnego stosowania wiersza poleceń CMD, PowerShella oraz Basha.

CMD vs PowerShell vs Bash

  • Model przetwarzania danych: CMD i Bash operują na czystych strumieniach tekstu; PowerShell przesyła w potokach silnie typowane obiekty .NET.
  • Wsparcie platformowe: CMD występuje wyłącznie w środowisku Windows NT; Bash dominuje w Linuksie; PowerShell Core jest narzędziem wieloplatformowym.
  • Wydajność uruchomieniowa: cmd.exe charakteryzuje się natychmiastowym startem i minimalnym zużyciem pamięci RAM w porównaniu z PowerShell.
  • Kiedy wybierać CMD: utrzymanie starszych skryptów logowania, środowiska ratunkowe Windows PE oraz proste jednowierszowe zadania automatyzacji.
Paradygmat przetwarzania powłoki: sposób reprezentacji i wymiany informacji pomiędzy narzędziami w wierszu poleceń. Wyróżnia się paradygmat tekstowy (strumienie znaków ASCII/UTF-8 parsowane narzędziami filtracyjnymi) oraz paradygmat obiektowy (pełne obiekty z metodami i właściwościami przekazywane w pamięci).
:: CMD - proste i skuteczne dla podstawowych zadan
@echo off
setlocal
set "PLIK=%1"
if exist "%PLIK%" (
    echo Plik istnieje: %PLIK%
) else (
    echo Plik nie istnieje.
)
endlocal

:: PowerShell - lepsze dla zlozonych operacji
:: Get-Process | Where-Object {$_.CPU -gt 100}

:: BASH - dobre dla skryptow wieloplatformowych
:: if [ -f "$1" ]; then echo "File exists"; fi
45/45
Podsumowanie i źródła do dalszej nauki
Slajd rekapituluje kluczowe zagadnienia programowania wsadowego w cmd.exe, podsumowuje zasady bezpiecznego kodowania oraz wskazuje literaturę źródłową.

Co omówiliśmy w ramach kursu

  • Fundamenty składni: struktura plików .cmd, ukrywanie poleceń (@echo off), hermetyzacja zmiennych (setlocal/endlocal) oraz opóźnione rozwijanie.
  • Struktury sterujące: pętle for (/L, /D, /R, /F), procedury z instrukcją call, obsługa parametrów (%~dp0) oraz kody błędów (%ERRORLEVEL%).
  • Praktyczne zastosowania: budowa skryptów backupu, instalatorów z menu interaktywnym, bezpieczne logowanie oraz manipulacja plikami robocopy.
  • Rekomendowane źródła wiedzy: oficjalna dokumentacja Microsoft Learn, kompendium SS64, portal Rob van der Woude oraz publikacje PTI.
Inżynieria skryptowa (scripting engineering): dziedzina inżynierii oprogramowania zajmująca się projektowaniem, implementacją, testowaniem i wdrażaniem powtarzalnych procedur automatyzacji administracyjnej z zachowaniem rygorów bezpieczeństwa, odporności na błędy oraz czytelności kodu.
:: ============================================
:: SPRAWDZ WIEDZE - przykładowe zadania
:: ============================================

:: 1. Napisz skrypt przyjmujacy 2 liczby i wyswietlajacy ich sume

:: 2. Napisz skrypt ktory sprawdza czy plik istnieje
::    i wyswietla informacje o nim

:: 3. Napisz skrypt backupu z automatycznym
::    znacznikiem czasu

:: 4. Napisz menu z trzema opcjami:
::    - Wyswietl date
::    - Wyświetl listę plików
::    - Zakoncz

:: 5. Napisz skrypt wyszukujacy wszystkie pliki
::    .txt w katalogu i podkatalogach

:: Powodzenia!