(Dit artikel verscheen eerder in het Septembernummer van Windows en Netwerken)

Batch to the Roots!

Als sinds het prille begin zit er in de Microsoft besturingssystemen een vorm van scripttaal genaamd batch. Helaas is het ook al lange tijd zo dat deze taal net iets te weinig functionaliteit biedt en dat er voor de meer ingewikkelde scripts al snel uitgeweken moet worden naar aparte talen zoals Kixtart, Perl en Windows Scripting Host.
Zonder dat Microsoft daar veel ruchtbaarheid aan heeft gegeven hebben ze de batchtaal onder Windows NT en Windows 2000 behoorlijk uitgebreid middels de zogenaamde 'command extensions'. De bestaande batch commando's zijn voorzien van extra opties die de batchtaal ineens onverwacht krachtig maken. Het moge zo zijn dat er ondertussen een flink aantal krachtige talen bestaat deze moeten echter over het algemeen apart geïnstalleerd worden of zijn slechts in bepaalde versies van Windows standaard aanwezig. Het voordeel van (NT)batch is dat het altijd aanwezig is ongeacht de versie van Windows NT en dat we ervan verzekerd kunnen zijn dat onze commando's zullen werken.

Er zijn vier commando's in NT-batch die belangrijk uitgebreid zijn en die daardoor wat meer aandacht verdienen. In dit artikel zal ik een beschrijving geven wat er precies is verandert en waarom dit interessant is. Als afsluiting zullen we met een voorbeeldscript deze extra functionaliteit beproeven aan de hand van een praktisch voorbeeld.
De commando's waar het vooral om gaat zijn het SET, IF, FOR en GOTO commando.

SET

Dit commando is zoals bij de meeste van u bekend is bedoeld om een omgevingsvariabele te voorzien van een waarde of deze aan te passen. Een aantal omgevingsvariabelen zoals bijvoorbeeld %COMPUTERNAME% en %USERNAME% zijn standaard in het systeem voorzien van vaste waarden en kunnen in een script van pas komen. Toevoegingen aan het commando SET zijn:

    De set/a en set/p syntax. Set/a maakt het mogelijk rekenwerk te verrichten. Set /p maakt het mogelijk om een gebruiker van het script gegevens in te laten voeren, een mogelijkheid die altijd slecht ontwikkelt is geweest in batch.  Daarnaast zijn er uitgebreidere mogelijkheden ontstaan voor substitutie zoals  %PATH:str1=str2%, hier wordt in de pad variabele een waarde vervangen door een ander. We kunnen nu ook een stuk van een variabele gebruiken met de syntax %PATH:~10,5%, geef de eerstvolgende 5 tekens na de tiende positie. Om het gebruik van samengestelde commando's te vergemakkelijken is de /V parameter toegevoegd. Voorheen kon een commando als 'for %i in (*) do set LIST=%LIST% %i' niet gebruikt worden omdat de varabele LIST voor het IF commando werd geëvalueerd in plaats van tijdens. Als een opdrachtregel is gestart met de /V parameter wordt dit probleem opgelost. Tenslotte zijn er een aantal gereserveerde variabelen toegevoegd die het scripten eenvoudiger maken.

Tabel 1: Nieuwe omgevings varabelen

  • %CD% - De huidige map.
  • %DATE% - De datum.
  • %TIME% - Tijd
  • %RANDOM% - Een willekeurig getal tussen  0 en 32767.
  • %ERRORLEVEL% - De huidige waarde van ERRORLEVEL
  • %CMDEXTVERSION% - Het versie nummer van command extensions
  • %CMDCMDLINE% - De opdrachtregel toen dit script werd gestart.

IF

Dit commando is natuurlijk geweldig belangrijk om binnen een script andere routes te kiezen op basis van bepaalde gegevens. Het aantal verbeteringen aan dit commando is relatief klein en bevat de volgende verbeteringen:

  • IF [/I] string1 compare-op string2 command
  • IF CMDEXTVERSION number command
  • IF DEFINED variable command

Met de /I parameter worden hoofdletters en kleine letters genegeerd. 'Compare-op' zijn de stringoperators als EQU en NEQ. De DEFINED waarde controleert of een varabele aanwezig is en met CMDEXTVERSION kan gecontroleerd worden of we met de juiste versie van 'commando extensions' te maken hebben in het geval dat hierop later nog uitbreidingen komen.

FOR

Dit commando heeft de grootste veranderingen ondergaan. In tabel 2 kunt u zien welke parameters er allemaal zijn bijgekomen. Het FOR commando is door al die parameters onverwacht krachtig geworden en is nu ook geschikt om directory structuren te controleren of bestanden te bewerken.

Tabel 2 : FOR commando extensions

  • /D FOR werkt nu met map in plaats van bestandsnamen
  • /R Wandel door een mapstructuur en voer FOR uit voor elke MAP
  • /L Maakt FOR tot het commando bekend uit vele talen
  • /F Lees een set bestanden, string of commando output.

Tabel 3 : Variabele substitutie van FOR

Waarde  Vervangt %I door

%~I               Verwijdert aanhalingstekens
%~fI              De volledige padnaam
%~dI             Schijfletter
%~pI             Het pad
%~nI             Bestandsnaam
%~xI              Extensie
%~sI              Pad met korte filenamen
%~aI             Bestandsattributen
%~tI              Datum/tijd van het bestand
%~zI             Bestandsgrootte
%~$PATH:I   Volledige pad van de eerste file die voldoet aan de zoekvoorwaarden in het pad.

De kracht van het FOR commando is misschien nog het beste zichtbaar door een aantal korte voorbeelden:

FOR /R C:\WINNT %%I IN (*.BMP) DO echo Aanwezige plaatjes : %%~nI met grootte : %%~zI bytes

Dit commando doorloopt de WINNT directory en geeft de naam (zonder extensie) en grootte van de gevonden bestanden.

FOR /F "usebackq tokens=1,2 delims==" %%i IN (`set`) DO @echo %%i heeft waarde: %%j

En deze voert het 'SET' commando uit, leest de uitvoer en verdeelt de output over %i en %j.

De twee genoemde commando's maken U naar ik hoop duidelijk dat het FOR commando een aantal interessante oplossingen kan hebben, niet alleen in scripts maar ook om snel handelingen vanaf een opdrachtregel uit te voeren.

GOTO

Een groot gemis van batchscripting is altijd het gebrek aan subroutines geweest. Dit was alleen oplosbaar door van subroutines aparte batchscripts te maken en die met call statements aan te roepen. In NT-batch echter wordt de mogelijkheid geboden om door een combinatie van het 'CALL' en 'GOTO' commando subroutines in batchscripts te implementeren, dit wordt door het volgende voorbeeld geïllustreerd:

 

@echo off
FOR %%i IN ("c:\winnt\*.*") DO call :sub %%i
goto :eof

:sub
if /I "%~x1" NEQ ".EXE" echo %~f1
goto :eof

Dit script doorloopt de WINNT directory en geeft de filenaam door aan een subroutine die alle bestandsnamen zonder de .EXE extensie laat zien. Zonder de mogelijkheid om subroutines te gebruiken moeten alle commando's op de regel achter FOR plaatsvinden wat een nogal onoverzichtelijk, zoniet onmogelijk script tot gevolg heeft.

Een Voorbeeld

Laten we nu eens in een voorbeeld een aantal van de nieuwe eigenschappen toepassen. Stel dat we een netwerk hebben met een aantal Windows NT stations en we willen in een batchscript op al deze stations controleren of  daar een SYMBIOS SCSI adapter aanwezig is. De meest simpele manier zou zijn om te kijken of de driver aanwezig is, deze heet symc8xx.sys en bij aanwezigheid hiervan kunnen we concluderen dat we een positief resultaat hebben.

@echo off
FOR /F "usebackq tokens=1" %%i IN (`net view`) DO call :getstation %%i
goto :eof

:getstation
REM Spoor werkstations op in de net view output en filter bijgaande tekst weg
REM Initieer hierna een zoekcommando
rem pause
SET TEST=%1
if "%TEST:~0,2%" EQU "\\" call :checkfile %1
GOTO :EOF

:checkfile
REM controleer op SCSI driver
REM default shares en mappen worden hier gebruikt
rem pause
if EXIST "%1\c$\WINNT\system32\drivers\symc8xx.sys" ECHO Station %1 heeft SCSI
GOTO :EOF

Bovenstaand script voert de gewenste actie uit. Eerst bewerken we de output van het commando 'net view' om vast te stellen welke Windows NT/2000 machines in het huidige domein aanwezig zijn, uit de output filteren we alles weg wat geen stationsnaam bevat. Dit doen we door te kijken naar de karakters '\\' welke zich altijd voor een stationsnaam bevinden. De stationsnamen worden vervolgens gebruikt om in een volgende subroutine te controleren op het sync8xx.sys bestand. Wanneer we een machine vinden die aan de voorwaarden voldoet geven we een melding. Het is natuurlijk ook mogelijk om de meldingen te verzamelen in een bestand middels het commando 'echo %1 >> stations.log'

Zoals blijkt is NT batch nog lang niet dood en blijken er zich verrassende mogelijkheden te verbergen in deze oude taal. Voordeel van NT batch is vooral dat het altijd aanwezig is, waardoor het vrijwel altijd uitgevoerd kan worden. Iets wat in een meer heterogene omgeving belangrijk kan zijn. Daarnaast is NT-batch handig voor korte taken die met een paar regels code samen te stellen zijn,  dis is  met veel andere talen niet zo eenvoudig te realiseren.

W. Verveen is verbonden aan Highway Back-office Consulting een werkmaatschappij van de Ormer groep die gespecialiseerde ondersteuning biedt voor Windows NT en back-office applicaties, daarnaast beheert hij Win2K Wereld

E-mail: w.verveen@ormer.nl
Web: http://www.boc.highway.nl en http://www.win2kwereld.nl


privacy policy