knumskull
Goto Top

Batchscripte mit variablenübergabe

Aufruf einer Batch-Datei aus einer anderen Datei und übergabe eines Parameters (zurück)

Hi,

also ich habe 2 CMD-Files

cmd1.bat
@echo off
setlocal

call cmd2.bat
if "%_return%"=="2" goto TOLL  
if "%_return%"=="1" goto NICHTTOLL  
goto EOF

:TOLL
echo XXX
goto EOF

:NICHTOLL
echo YYY
goto EOF

:EOF

cmd2.bat
@echo off
setlocal
echo mache irgendwas
endlocal  & set _return=2

sowas in der Art will ich haben. Also ich rufe das 2. Batchfile aus dem ersten auf und benötige einen Rückgabewert.
ich habe das ganze auch schon mit
exit 1
exit 2
versucht, allerdings schiest mir ja dann die ganze shell ab.
Hat noch jemand eine Idee?

Gruß,
Steffen

Content-ID: 113561

Url: https://administrator.de/contentid/113561

Ausgedruckt am: 26.11.2024 um 06:11 Uhr

bastla
bastla 09.04.2009 um 09:38:12 Uhr
Goto Top
Hallo Knumskull!

Ohne "Shellabschuss": face-wink
exit /b 1
Die Übergabe per Variable (%_return%) sollte aber eigentlich ohnehin funktionieren ...

Grüße
bastla
colinardo
colinardo 09.04.2009 um 09:40:13 Uhr
Goto Top
Du kannst in Batch "cmd2.bat" Zeile 4 den errorlevel des vorherigen Befehls übergeben:
endlocal  & set _return=%errorlevel%
Knumskull
Knumskull 09.04.2009 um 09:54:25 Uhr
Goto Top
kann es einen zusammenhang mit

setlocal enableextensions
haben?

Ich bin mir auch sicher, das es funtkionieren sollte.

Das mit
exit /b 2
habe ich gerade auch schon versucht. allerdings will das auch nicht so recht funktionieren.

Irgendwie mag mich windows nicht face-sad
colinardo
colinardo 09.04.2009 um 10:03:55 Uhr
Goto Top
poste doch mal dein komplettes Script. So wie es oben steht funktioniert es bei mir ohne Probleme
Knumskull
Knumskull 09.04.2009 um 10:20:50 Uhr
Goto Top
okay face-smile ... es ist aber ein wenig länger face-smile ... Die Skripte sind in der Reihenfolge angegeben, wie sie aufgerufen werden. Mein Problem besteht in der Kommunikation zwischen 'common_checks.bat' und 'check_update_ws.bat'

set_cmd_env.bat
rem /+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
rem / Umgebungsvariablen setzen															/
rem / Diese Variablen sind in allen anderen Skripten verfuegbar							/
rem /+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/


rem # CAE-Samba-Umgebung initialisieren
set CAE_SAMBA=<entfernt>
set APPL_HOME=%CAE_SAMBA%\appl
set CAE_PAKET_HOME=%APPL_HOME%\_admin\cae-support
set CAE_PAKET_SKRIPT_HOME=%CAE_PAKET_HOME%\_admin\skript
rem Skriptpfad fuer lokale Entwicklung verbogen
::set CAE_PAKET_SKRIPT_HOME=%HOMEDRIVE%%HOMEPATH%\Desktop\cae-support-paket\skript-paket

rem # Skriptpfad der machine_list.txt
rem # Der Name der Datei 'machine_list.txt' wird als Parameter uebergeben  
::set CAE_PAKET_MACHINELIST=%CAE_PAKET_SKRIPT_HOME%\%1
rem folgende Zeile dient der Entwicklung
set CAE_PAKET_MACHINELIST=%CAE_PAKET_SKRIPT_HOME%\machine_list_dev.txt


rem # Benoetigte Applikationen in die Umgebung laden
set PSEXEC=%CAE_PAKET_HOME%\_admin\tools\psexec.exe
set PSEXEC_OPT=-s

rem # Skriptfiles des CAE-Samba Support-Paketes
set CAE_START_FILE=%CAE_PAKET_SKRIPT_HOME%\start.bat
set CAE_COMMON_CHECKS_FILE=%CAE_PAKET_SKRIPT_HOME%\common_checks.bat
set CAE_CHECK_UPDATE_WS_FILE=%CAE_PAKET_SKRIPT_HOME%\check_update_ws.bat
set CAE_MAKE_UPDATE_WS_FILE=%CAE_PAKET_SKRIPT_HOME%\make_update_ws.bat

rem # Tempfile
set CAE_TEMPFILE=%TEMP%\cae_support_tmp_file.txt



start.bat
@echo off
goto BEGIN


rem /+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
rem / Umgebungsvariablen setzen															/
rem / Diese Variablen sind in allen anderen Skripten verfuegbar							/
rem /+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
:BEGIN
setlocal 
::enableextensions

rem # Umgebung laden
set CAE_SUPPORT_ENV=\\cae-samba.wob.vw.vwg\appl\_admin\cae-support\_admin\skript
call "%CAE_SUPPORT_ENV%"\set_cmd_env.bat  


rem /+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
rem / Beginn des Skriptes																/
rem / Aenderungen ab hier, koennen den Ablauf beinflussen								/
rem /+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/

if not "%1"=="" (  
  goto CRONJOB
) else (
  goto MANUAL
)

:CRONJOB
  if exist "%CAE_PAKET_MACHINELIST%" (  
	rem # Wenn die Liste vorhanden ist, wird die Datei 'common_checks.bat' aufgerufen	  
	set CMD=%CAE_COMMON_CHECKS_FILE%
	set CMD_EXT=%CAE_PAKET_MACHINELIST%
	goto NEXT_SKRIPT
  )
goto EOF


:MANUAL
rem # manueller Aufruf der 'start.bat' fuer die Neuinstallation des CAE-Samba Paketes  
  :LOOP
  cls
  echo ****************************
  echo * CAE-Samba Support-Paket  *
  echo *--------------------------*
  echo * Manuelle Rechneraufnahme *
  echo ****************************
  echo .
  set /p WS_NAME=Rechnername eingeben [Abbruch mit Return]: 
  rem # testen ob Eingabe leer
  if "%WS_NAME%"=="" (  
    echo Eingabe abgebrochen!
	goto EOF
  )
  rem # Test ob der Rechner erreichbar ist.
  ping -n 1 %WS_NAME% >NUL 2>&1
  if errorlevel 1 goto ERROR
  goto WEITER
    :ERROR
    rem # Farbe auf rot/weiss aendern
    color CF
	echo Der Rechner %WS_NAME% kann nicht erreicht werden.
	set /p check=Eingabe wiederholen? [j/n] 
	if /I "%check%"=="j" (  
	  color
	  goto LOOP
	)
	if /I "%check%"=="n" (  
	  color
	  goto EOF
	)
  :WEITER
  rem # beim manuellen Aufruf, ist der Common-check nicht notwendig.
  rem # Dieser Part wird uebersprungen und es wird gleich 'check_update.bat' ausgefuehrt.  
  set CMD=%CAE_CHECK_UPDATE_FILE%
  set CMD_EXT=%WS_NAME%
  )
  goto NEXT_SKRIPT


:NEXT_SKRIPT
rem # ruft das Skript start.bat mit den entsprechenden Parametern auf
::echo "%CMD%" "%CMD_EXT%" 
call "%CMD%" "%CMD_EXT%"  
if errorlevel 1 goto ERROR_COMMON
goto EOF

:ERROR_COMMON
echo Fehler beim Aufruf der Datei 'common_checks.bat'  

:EOF
endlocal
rem exit 0
pause

common_checks.bat
@echo off
goto BEGIN

:BEGIN
setlocal 
::enableextensions

set LOCAL_MACHINELIST=%TEMP%\loc_machine_list.txt

rem # lokale Kopie der 'machine_list.txt' anlegen, fuer den Fall das eine Abarbeitung laenger als  
rem # 5 Minuten dauert. Somit ist Sichergestellt, dass keine Probleme aufgrund von Dateizugriffen
rem # entstehen.
copy /Y "%CAE_PAKET_MACHINELIST%" "%LOCAL_MACHINELIST%" >NUL 2>&1  
if errorlevel 1 goto ERROR_COPY
goto SCHLEIFE

:SCHLEIFE
rem # Jeden einzelnen Eintrag in der 'machine_list.txt' abarbeiten  
cls
FOR /F "delims=\n" %%I IN (%LOCAL_MACHINELIST%) DO (  
  rem # Test ob der Rechner erreichbar ist.
  ping -n 1 %%I >NUL 2>&1
  if errorlevel 1 break
  

  rem # wenn erreichbar, wird die Datei 'check_update_ws.bat' auf dem Rechner gestartet.  
  rem %PSEXEC% %PSEXEC_OPT% \\%%I cmd /C "%CAE_CHECK_UPDATE_WS_FILE%" >NUL  
  call %CAE_CHECK_UPDATE_WS_FILE% %%I
::  echo _return: %_return%
  echo ERRORLEVEL: %errorlevel%
  if "%errorlevel%"=="55" (  
    echo Die Maschine %%I benoetigt ein Update!
    goto NEXT
  )
  if "%errorlevel%"=="0" (  
    echo Die Maschine %%I benoetigt KEIN Update!
  goto NEXT
  )
  
  :NEED_UPDATE
  ::echo Errorlevel: %errorlevel%
  echo Die Maschine benoetigt ein Update!
  goto NEXT
  
  :NO_UPDATE
  ::echo Errorlevel: %errorlevel%
  echo Die Maschine  benoetigt KEIN Update!
  goto NEXT
  
  :NEXT
  break
)

rem lokale Kopie der 'machine_list.txt' wieder entfernen  
del /F %LOCAL_MACHINELIST%
if errorlevel 1 goto ERROR_TMPDEL
goto EOF

:ERROR_COPY
echo Fehler beim kopieren der Datei: %CAE_PAKET_MACHINELIST%
goto EOF

:ERROR_TMPDEL
echo Fehler beim loeschen der Datei: %LOCAL_MACHINELIST%
goto EOF

:EOF
rem exit 0
endlocal

check_update_ws.bat
@echo off
goto BEGIN

:BEGIN
setlocal 
:: enableextensions

rem # Umgebung laden
set CAE_SUPPORT_ENV=\\cae-samba.wob.vw.vwg\appl\_admin\cae-support\_admin\skript
call "%CAE_SUPPORT_ENV%"\set_cmd_env.bat"  

rem # Zu checkender Rechner
set REMOTE_WS=%1

rem # Local tempfile
set LOC_TEMPFILE=%TEMP%\cae_support_tmp-file.txt

rem # Environment-File
::set CAE_ENV_FILE=%CAE_PAKET_HOME%\CAE-environment.reg
set CAE_ENV_FILE=%CAE_PAKET_SKRIPT_HOME%\CAE-environment.reg

rem # aktuelle Version in Tempfile schreiben
type %CAE_ENV_FILE%|find "version" > %LOC_TEMPFILE%  

set /p CAE_VER=<"%LOC_TEMPFILE%"  
rem # nur auf das Datum beschneiden
set CAE_VER=%CAE_VER:~11,16%

reg query "\\%REMOTE_WS%\HKEY_LOCAL_MACHINE\SOFTWARE\CAE-Support\CAE-Berechnungsumgebung" | find "%CAE_VER%" >NUL  
::reg query "HKEY_LOCAL_MACHINE\SOFTWARE\CAE-Support\CAE-Berechnungsumgebung" | find "%CAE_VER%" >NUL 
if errorlevel 1 goto MAKE_CAE_UPDATE
goto AKTUELLE_VERSION

:MAKE_CAE_UPDATE
del /F %LOC_TEMPFILE%
endlocal
exit /B 55
goto EOF


:AKTUELLE_VERSION
del /F %LOC_TEMPFILE%
echo 321
endlocal
exit /B 0
goto EOF

:EOF
bastla
bastla 09.04.2009 um 10:37:29 Uhr
Goto Top
Hallo Knumskull!

Das Problem besteht darin, dass der Errorlevel innerhalb der "for /f"-Schleife (aus Zeile 20) ausgewertet werden soll - ohne "delayedExpansion" wird aber der Wert der Variablen (eben auch von %errorlevel%) bereits zu Beginn der Schleife ermittelt ...

Funktionieren sollte aber
if errorlevel 55 (
oder, wenn es keiner weiterer Unterscheidung bedarf, einfach (da bei "if errorlevel" immer eine Abfrage auf ">=angegebener Wert" erfolgt):
if errorlevel 1 (
    echo Die Maschine %%I benoetigt ein Update!
) else (
    echo Die Maschine %%I benoetigt KEIN Update!
)
Damit hättest Du dann beide Fälle abgedeckt.

Grüße
bastla
Knumskull
Knumskull 09.04.2009 um 10:52:56 Uhr
Goto Top
Danke für die Antwort, aber so richtig verstehen tue ich die nciht face-smile

Das Problem an der Sache ist, dass nach

Zeile: 28
call %CAE_CHECK_UPDATE_WS_FILE% %%I

der errorlevel == 0 ist. demnach kann ich verknüpfen, was ich möchte. Ich habe immer 0. Auf das
exit /b 55
reagiert die shell gar nicht

was hat es mit dem delayedexpansion auf sich? Wo ist das mal gut beschrieben, oder kannst du mir das ein bissl näher bringen?

*P.S.: gibt es ein gutes Buch über Batch-Scripting?
Knumskull
Knumskull 09.04.2009 um 11:07:53 Uhr
Goto Top
okay, das mit dem delayedexpansion hab ich soweit verstanden. (warum macht man sowas) *OMG*

Mein Problem ist jetzt gerade noch, das die FOR-Schleife in Zeile 20 irgendwie nicht sauber arbeitet.

gewollt ist, das die Schleife die Datei Zeilenweise abarbeitet.

in der Datei stehen Computernamen
computer1
computer2
computer3

Aber so wie es für mich aussieht, wird nur der erste Eintrag genommen? Woran kann das liegen?
Knumskull
Knumskull 09.04.2009 um 12:00:41 Uhr
Goto Top
ich habe die For-Schleife jetzt mal ein wenig umgebaut. So funktioniert es eigentlich ganz gut. Allerdings nur für den ersten Computer. Beim zweiten unterscheidet er irgendwie nicht mehr zwischen den Errorleveln. Siehe Ausgabe. Woran könnte das liegen?


FOR /F "delims=" %%I IN (%LOCAL_MACHINELIST%) DO (  
  rem # Test ob der Rechner erreichbar ist.
  ping -n 1 %%I >NUL 2>&1
  if not errorlevel 1 (
	rem # wenn erreichbar, wird die Datei 'check_update_ws.bat' auf dem Rechner gestartet.  
	rem %PSEXEC% %PSEXEC_OPT% \\%%I cmd /C "%CAE_CHECK_UPDATE_WS_FILE%" >NUL  
	call %CAE_CHECK_UPDATE_WS_FILE% %%I
	rem # Debug
	echo !ErrorLevel: !errorlevel!
	echo %ErrorLevel: %errorlevel%
	if errorlevel 55 (
	  echo Die Maschine %%I benoetigt ein Update!
	)
	if errorlevel 10 (
		echo Die Maschine %%I benoetigt KEIN Update!
	)
  )
)

Ausgabe:
ErrorLevel: 10
ErrorLevel: 0
Die Maschine Computer1 benoetigt KEIN Update

Error:  Zugriff verweigert
ErrorLevel: 55
ErrorLevel: 0
Die Maschine Computer2 benoetigt ein Update
Die Maschine Computer2 benoetigt KEIN Update
Drücken Sie eine beliebige Taste . . .
Knumskull
Knumskull 09.04.2009 um 12:36:58 Uhr
Goto Top
jetzt hab ich es soweit fertig.

	if errorlevel 55 ( 
	  echo Die Maschine %%I benoetigt ein Update! 
	) 
	if errorlevel 10 ( 
		echo Die Maschine %%I benoetigt KEIN Update! 
	) 

is klar, wenn errorlevel 55, denn is das ja auch größer 10 ... also beide ausgaben ...

und ein GOTO kann man nicht einbauen, weil er dann die schleife nicht weiter abarbeitet. Alles ziemlich Trickreich.

Jetzt suche ich nur noch eine Sache, das aber besser in einem anderen Thema.

Bleibt nur noch die Frage nach dem Buch ;)

Gruß,
STeffen
bastla
bastla 09.04.2009 um 14:51:31 Uhr
Goto Top
is klar, wenn errorlevel 55, denn is das ja auch größer 10 ... also beide ausgaben ...
Wenn es doch aber ein klarer Fall von "entweder - oder" ist, warum dann nicht die oben dargestellte Konstruktion mit dem "else"?

Grüße
bastla

P.S.: Buchtipp habe ich leider keinen zu bieten (aber ein gutes Forum wüsste ich face-wink) ...
Knumskull
Knumskull 09.04.2009 um 15:10:27 Uhr
Goto Top
ist es nicht mehr :D ... ich war ja noch nicht fertig.

so sieht es jetzt aus.
FOR /F "delims=" %%I IN (%LOCAL_MACHINELIST%) DO (  
  rem # Test ob der Rechner erreichbar ist.
  ping -n 1 %%I >NUL 2>&1
  if not errorlevel 1 (
	rem # wenn erreichbar, wird die Datei 'check_update_ws.bat' auf dem Rechner gestartet.  
	call %CAE_CHECK_UPDATE_WS_FILE% %%I
	rem # Debug
	rem echo !ErrorLevel: !errorlevel!
	rem echo %ErrorLevel: %errorlevel%
	if !errorlevel! equ 55 (
	  echo %%I: benoetigt Update!
	  rem echo.
	) 
	if !errorlevel! equ 20 (
	  rem # Keine CAE-Berechnungsumgebung installiert.
	  echo %%I: Keine CAE-Berechnungsumgebung installiert!
	  rem echo.
	)
	if !errorlevel! equ 10 (
	  rem # Keine Adminrechte
	  echo %%I: Kein Zugriff, eventuell fehlen die Adminrechte!
	  rem echo.
	)
	if !errorlevel! equ 0 (
	  echo %%I: aktueller Stand.
	  rem echo.
	)
  )
)
bastla
bastla 09.04.2009 um 15:23:19 Uhr
Goto Top
Hallo Knumskull!

So sollte es natürlich dann auch gehen - oder, etwas entspannter face-wink (und ohne "delayedExpansion"):
FOR /F "delims=" %%I IN (%LOCAL_MACHINELIST%) DO (  
  rem # Test ob der Rechner erreichbar ist.
  ping -n 1 %%I >NUL 2>&1 && call :Check "%%i"  
)
goto :eof

:Check
rem # da erreichbar, wird die Datei 'check_update_ws.bat' auf dem Rechner gestartet.  
call %CAE_CHECK_UPDATE_WS_FILE% %1
rem # Debug
rem echo %ErrorLevel: %errorlevel%

if %errorlevel%==55 goto :Update
if %errorlevel%==20 goto :KeineCAE
if %errorlevel%==10 goto :KeinAdmin
if %errorlevel%==0  goto :Aktuell

echo %~1: Unbekannter Fehler %errorlevel%
rem echo\
goto :eof

Update
echo %~1: benoetigt Update!
rem echo.
rem ...
goto :eof
 
:KeineCAE
rem # Keine CAE-Berechnungsumgebung installiert.
echo %~1: Keine CAE-Berechnungsumgebung installiert!
rem echo.
goto :eof

:KeinAdmin
rem # Keine Adminrechte
echo %~1: Kein Zugriff, eventuell fehlen die Adminrechte!
rem echo.
goto :eof

:Aktuell
echo %~1: aktueller Stand.
rem echo.
goto :eof
Grüße
bastla
Knumskull
Knumskull 09.04.2009 um 15:59:11 Uhr
Goto Top
sieht sehr gut und interessant aus. nehm ich einfach mal so mit face-smile
allerdings hat es beim einsetzten nicht gleich funktioniert. Daher lege ich das erstmal auf Eis und behalte diese Version im Hinterkopf.

Danke auf jedenfall, hast mir sehr gut geholfen ;)

gruß,
STeffen