Programování v příkazové řádce
Možná o tom nevíte, ale i přímo v příkazové řádce Windows se dá (téměř) plnohodnotně programovat. V tomto okamžiku nemám na mysli skripty ve VBScriptu ani JScriptu, ale přímo příkazového interpretru. Naučím vás tedy některé užitečné fígle.
Poznámka: použité příklady jsou ke stažení na adrese http://www.sevecek.com/res/clanky/cmd.
Základy práce s příkazovou řádkou
Příkazovou řádku (interpretr) spustíte ve Windows NT, 2000, XP, 2003 (a novějších J) tak, že spustíte program CMD.EXE (stačí napsat CMD). Jedná se plně o 32-bitovou aplikaci pracující s textovým výstupem (tzv. console application, konzolová aplikace, někdy nesprávně nazývané DOSové okno). Pozor, je možno spustit také COMMAND.COM, ale tím startuje pravý 16-bitový MS-DOS (běží v emulaci) což je cesta zpátky a dále se tím nebudeme zabývat.
Ukončit program CMD je možné zadáním příkazu EXIT.
Příkazová řádka přijímá některé notoricky známé příkazy podle následující tabulky. Jedná se přímo o příkazy interpretru, jejichž obdobu nenajdete nikde na disku v podobě .EXE souboru.
| CD „cesta k adresáři“ | Přepne aktuální adresář na zadanou cestu |
| DIR | Vypíše obsah aktuálního, nebo zadaného adresáře |
| DEL | Smaže zadaný soubor, nebo prázdný adresář |
| RMDIR | Smaže zadaný adresář a případně všechny jeho podadresáře a soubory |
| MKDIR | Vytvoří nový adresář |
| COPY | Zkopíruje soubor (nelze použít na adresář) |
| XCOPY | Zkopíruje soubor, nebo i adresář (tohle je jen pro ukázku, nejedná se o příkaz interpretru, ale o skutečný .EXE soubor, který máte v adresáři System32) |
Několik poznámek:
- existují dva typy příkazů – příkazy interpretru a spustitelné .EXE soubory. Příkazy interpretru neexistují nikde ve formě .EXE a rozumí jim jen interpretr. Je ale možné spouštět také libovolný .EXE soubor zapsáním přímo jeho jména (s/bez jeho cesty na disku, případně s/bez jeho přípony .EXE)
- parametry příkazů (spustitelných programů i příkazů interpretru) se vždy oddělují mezerou. Pokud je v hodnotě parametru obsažena mezera, musí se celá obalit do uvozovek (normální české dvojité uvozovky)!
Cesta k souboru a adresáři
Cestu k souboru můžete zapsat relativně vzhledem k aktuálnímu adresáři (přepnete se do něho pomocí CD), nebo absolutně. Pokud se nebojíte opotřebovat si trošku prsty, vždycky cesty obalujte do uvozovek – pokud náhodou obsahuje mezeru, vyhodnotilo by se to jako dva parametry.
Příklady:
| „c:\program files\Internet Explorer\iexplore.exe” | Absolutní cesta i s diskem |
| „\program files\Internet Explorer\iexplore.exe” | Cesta relativní ke kořenu aktuálního disku |
| „Internet Explorer\iexplore.exe” | Cesta relativní k aktuálnímu adresáři |
| „\Internet Explorer\iexplore.exe” | Pozor! Opět cesta relativní ke kořenu disku |
| c:\program files\Internet Explorer\iexplore.exe | Pozor! Celkem 3 různé cesty (není to v uvozovkách) - c:\program - files\Internet - Explorer\iexplore.exe |
| \\server\share\podcesta | Cesta ke sdílenému adresáři |
| CD \ nebo i bez mezery CD\ | Přepne aktuální adresář na kořen disku |
| CD E:\ | Pozor! Přepne aktuální adresář disku E: na jeho kořen, ale zobrazen zůstane původní disk (např. C: ) |
| E: | Přepne na disk E: do jeho aktuálního adresáře |
Nápověda k příkazům
Každý příkaz i konzolový program má dostupnou nápovědu (většinou lokalizovanou). Zkuste například:
CMD /H
DIR /H
DEL /H
XCOPY /H
Nápovědu, a mnohdy velmi obsáhlou, najdete v helpu k Windows. Nechte si jendoduše vyhledat sousloví “command reference”, ale bez uvozovek).
Příkazové skripty .BAT a .CMD
Prozatím jste psali příkazy přímo do příkazové řádky. Silou příkazové řádky jsou ale její skripty. Stačí si vytvořit textový soubor s příponou .BAT (nebo.CMD, to je stejné) a do něj zapsat všechny příkazy, které normálně píšete do příkazové řádky. Poznamenejme, že jména příkazů jsou case insensitive (je možné je psát bez ohledu na velikost písmen)
Takový skript může vypadat následovně:
---- PRVNI.BAT:
@Echo off
Echo Nasleduje aktualni datum a cas:
Date /T
Echo.
Time /T
rem Vystup prikazu DIR bude v souboru C:\prvni.txt
Echo Vypis souboru v aktualnim adresari > c:\prvni.txt
DIR >> c:\prvni.txt
set /P =Stisknete ENTER.
Ve výpisu objevíte výstupy dvou příkazů pro zjištění data a času. Úvodní klauzule @Echo off zajistí, že se jednotlivé příkazy nebudou vypisovat (jejich výstup se vypisovat samozřejmě bude). Příkaz Echo vypisuje pouze text. Pokud chcete do výstupu programu přidat volný řádek, musíte to udělat pomocí Echo. . Poznámka je celořádková a uvádí se příkazem REM.
Poslední řádek ve výpisu zajistí, že program počká, dokud nestisknete ENTER. Jinak by skript po spuštění jenom problikl a vy byste neviděli jeho výstup.
Přesměrování výstupu
Jednotlivé příkazy vypisují svůj výstup do tzv. standardního výstupu (stdout). Tento je normálně na obrazovku, ale je možné ho přesměrovat (redirect) také do souboru. To je právě přiklad příkazu DIR. Existují dvě možnosti:
| > “jmeno souboru“ | Přesměruje výstup, ale nejprve soubor znovu vytvoří (přepíše existující) |
| >> “jmeno souboru“ | Výstup se přidá na konec souboru, pokud již existuje. Jinak se vytvoří nový soubor. |
| > NUL | Anihilace. Těžko pochopitelné, ale je to tak. (Pozor! Jenom jedno L) |
Přesměrování je bezva například při ladění. Pokud vytváříte logon skripty, můžete později zjistit, co se vlastně na počítači stalo, nebo většinou spíše nestalo.
Přesměrování výstupu na vstup jiného programu
Existují programy (příkazy), které přijímají vstup a něco s ním provádějí. Například program FINDSTR umí svůj vstup filtrovat řádek po řádku a vypisovat jen ty řádky, které odpovídají nějakému regulárnímu výrazu. Pěkně je to vidět na výstupu dalšího programu NETSTAT, který vám řekne, jaká TCP spojení jsou navázána z/na váš počítač:
---- PIPE.BAT:
@ECHO OFF
netstat -an
Echo.
Echo Filtrovany vystup:
Echo.
netstat -an | findstr /C:"445"
set /P =Stisknete ENTER.
Program nejprve vypíše všechny otevřené TCP a UDP porty a potom vyfiltruje jen řádky, které obsahují text 445 (tedy sdílení souborů firmy Microsoft, které máte nejspíš všichni). Důležité je použití znaku | nazývaného pipe (roura známá z Unixu). Ten přesměruje výstup programu NETSTAT na vstup programu FINDSTR.
Práce s parametry
Každý .BAT soubor, stejně jako jiné programy je možno spustit s parametry. K parametrům se dostanete jednoduše pomocí konstant %1, %2, %3 až %9. Existuje také %0, která obsahuje celou cestu k vašemu .BAT souboru a %* což jsou všechny parametry dohromady.
Poznámka: skript můžete spustit také tak, že na jeho ikonku přetáhnete v průzkumníkovi nějaké soubory (to budou potom jeho parametry).
---- PARAMETRY.BAT
@ECHO OFF
ECHO Skript: %0
ECHO Parametr 1: %1
ECHO Parametr 2: %2
ECHO.
ECHO Vsechny parametry: %*
ECHO.
ECHO Disk: %~d1
ECHO Cesta: %~p1
ECHO Soubor: %~n1
ECHO Pripona: %~x1
ECHO Velikost: %~z1
set /P =Stisknete ENTER.
Pokud parametr napíšete s uvozovkami, ve vašem skriptu bude už bez uvozovek.
Existují jistá kouzla s parametry, pokud se jedná o jméno souboru (číslo vždy značí číslo parametru):
| %~d1 | Vrátí jen písmeno disku |
| %~p1 | Vrátí cestu k adresáři ve kterém je soubor |
| %~n1 | Dává jen samotné jméno souboru |
| %~x1 | Dává jen příponu jména souboru |
| %~z1 | Vrátí velikost souboru |
Podmínka IF a skoky
S použitím parametrů úzce souvisí také podmínky a případně skoky:
---- PODMINKY.BAT
@ECHO OFF
IF "%1" == "" Echo Skript byl spusten bez parametru.
IF EXIST "%1" Echo Soubor %1 existuje.
IF NOT EXIST "%2" Echo Soubor %2 neexistuje.
IF "%3" == "konec" GOTO Navesti1
Echo Parameter cislo 3 nebyl roven "konec"
:Navesti1
IF /I "%4" NEQ "Text" (
Echo Parametr 4 neni "Text" ani "tEXT" ani "tExT" ani ...
Echo a jeste aktualni cas
Time /T
)
set /P =Stisknete ENTER.
Klíčové slovo EXIST testuje, zda soubor existuje. Klíčové slovo GOTO provede skok na návěští. Operátor NEQ (not equal) rozhodne o nerovnosti (spolu s přepínačem /I, který označuje ignorování velikosti písmen). Blok více příkazů je možno obalit do kulatých závorek.
Důrazně doporučuji vždy obalovat konstanty parametrů uvozovkami! Pokud se totiž parametr nevyskytuje (nebyl zadán), bez uvozovek program nebude fungovat. S uvozovkami se například první podmínka (správně) vyhodnotí jako:
IF "" == "" Echo …
Proměnné
Zkuste si do příkazové řádky napsat příkaz SET. Dostanete seznam tzv. proměnných prostředí (environment variables). Jedná se o proměnné definované systémem (některé jde předefinovat, některé ne). Jejich hodnoty je možné použít například takto (soubor by se zkopíroval tam, kde zrovna máte adresář s programy):
COPY soubor.txt %ProgramFiles%
Důležité, automaticky definované proměnné:
| %USERNAME% | Jméno uživatele, pod kterým běží kript |
| %DOMAINNAME% | Jméno domény uživatele, do které je přihlášen |
| %COMPUTERNAME% | Je myslím jasné |
| %LOGONSERVER% | Jméno serveru, pomocí kterého proběhlo přihlášení (to je velice důležité, protože je například ve vaší “site”, pokud víte, co to znamená): - %logonserver%\netlogon – je adresář s logon skripty |
| %WINDIR% | Adresář, kam jsou nainstalované Windows (je k dispozici i na Windows 98) |
| %SYSTEMROOT% | Stejné jako WINDIR, ale tahle proměnná není k dispozici na Windows 98. |
Je možné vytvářet si i vlastní proměnné a dokonce s nimi i počítat, nebo si je nechat zadávat uživatelem. Existují i větší machrovinky:
---- PROMENE.BAT:
@ECHO OFF
SET /P jmeno=Zadejte jmeno:
Echo Vase jmeno:
Echo %jmeno%
SET /P cislo=Zadejte cislo:
SET /A vysledek=%cislo% * 5
Echo Vypocet: %cislo% * 5 = %vysledek%
SET /P retezec=Zadejte text delsi nez 10 znaku:
Echo Poslednich 5 znaku: %retezec:~-5%
Echo Znaky cislo 3-8: %retezec:~3,5%
Echo Cely retezec bez poslednich dvou znaku: %retezec:~0,-2%
set /P =Stisknete ENTER.
Pro vytváření proměnných se používá příkaz SET. Jen je důležité počítat s tím, že proměnná vydrží jen po dobu běhu vašeho skriptu. Vytvořit trvalou proměnnou je možné programem SETX, který je ale dostupný jen jako součást Support Tools.
Spouštění programů a dalších skriptů
Krátký, ale veledůležitý odstavec. Pokud ze skriptu zavoláte nějaký příkaz, nebo .EXE program, počká se dokud neskončí. To někdy nechcete, potom použijete příkaz START - je možné tak spouštět programy i s jinou prioritou (např. LOW):
START /LOW calc.exe
Důležitější je ale, že pokud chcete volat jiný skript .BAT (synchronně), musíte! to udělat pomocí příkazu CALL:
CALL skriptik.bat
V opačném případě (a nechápu proč) se už nikdy neprovede zbytek původního skriptu, který pokračoval za voláním.
Cyklus FOR
Bez cyklu není programování (teda to aspoň tvrdím já). Takže (veškerá věda je FOR /H):
---- CYKLY.BAT
@ECHO OFF
rem Od 1 do 12 s krokem 3
FOR /L %%A IN (1,3,12) DO (
ECHO %%A
)
rem Vypise vsechny soubory s priponou .BAT v aktualnim adresari
FOR %%B IN (*.BAT) DO (
ECHO %%B
)
rem Vypise vsechny soubory s priponou .BAT na celem disku
FOR /R C:\WINDOWS %%C IN (*.BAT) DO (
ECHO %%C
)
rem Z kazdeho radku v souboru vybere druhy a ctvrty sloupec oddeleny ; nebo mezerou
FOR /F "tokens=2,4 delims=; " %%M IN (cykly.txt) DO (
Echo Sloupec 2: %%M Sloupec 4: %%N
)
SET /P =Stisknete ENTER.
Pozor! Proměnná pro cyklus je uvedena dvěma %% na začátku. Všimněte si také, že cyklus FOR může provést nějakou akci i pro soubory v aktuálním adresáři.
Nejsilnější je ale jeho použití pro parsování textových souborů. Přepínač /F je schopen projet soubor řádek po řádku a každý rozložit na tzv. tokeny, tedy části oddělené určitými znaky. Zadáváte jenom jedinou proměnnou (v našem případě %%M), ve které je uložen první token. Abecedně další proměnné obsahují další tokeny (u nás %%N).
Specialitky pro fajnšmekry
Jak vypsat všechny parametry bez ohledu na jejich počet. SHIFT posune parametry doleva. Speciální návěstí :EOF ukončí skript.
---- VYPISPARAM.BAT
@ECHO OFF
:Vypis
IF "%1" == "" GOTO :eof
Echo %1
SHIFT
GOTO Vypis
Speciální proměnné, které pomocí příkazu SET neuvidíte:
| %CD% | Aktuální adresář |
| %CMDLINES% | Celá příkazová řádka se kterou byl skript spuštěn |
| %DATE% | Aktuální datum v proměnné (příkaz DATE ho jen vypíše) |
| %TIME% | Aktuální čas |
| %RANDOM% | Náhodné číslo (to je moje nejoblíbenější) |
Zjistit který je měsíc pomocí FOR (funguje jen pro české datum)? Použijte apostrofy pro parsování výstupu programu:
FOR /F "tokens=2 delims=." %%M IN ('DATE /T') DO Echo %%M
Program chce, abyste mu stiskli klavesu Y a vás už bolí ruka?
ECHO Y | CACLS *.* /G everyone:R
Chcete nahradit v řetězci tečky čárkami? Zase jeden speciální formát použití proměnné.
SET retezec=ondra.kamil.jitka.stanislav
SET retezec=%retezec:.=,%
ECHO %retezec%
A jako perlička je na výše uvedené adrese program NODELIST.BAT, který zjistí IP adresy okolních počítačů, jejich jména a MAC adresy.
Pěknou zábavu.