Eine Batch Datei bleibt immer wieder stehen
Batchdatei hängt sich immer wieder auf in Verbindung mit einem Schedule Task
Hallo,
ich habe ein Problem mit folgender Batchanwendung.
Die folgende Scriptanwendung wird über den Windows Scheduler jede Minute gestartet und abgearbeitet.
Wenn ich in das zu überwachende Verzeichnis Tesdateien kopiere, funktioniert alles einwandfrei.
Werden aber über eine entsprechende Applikation Dateien in das Verzeichnis geschrieben, hängt sich das Script oder der Scheduler auf.
Diese muss ich dann immer manuell stoppen und neu starten.
Eine Vermutung habe ich noch:
Kann es sein, wenn die Applikation Dateien schreibt, und dafür, ich sage mal 5 Minuten für eine Datei braucht,
die neue Datei gesperrt ist. Mein Script sich aber hier schon eine Variable merkt, mit dieser aber nichts anfangen kann und
sich so aufhängt.
Vielen Dank im Voraus für eine Idee.
Nun das besagt Script:
Hallo,
ich habe ein Problem mit folgender Batchanwendung.
Die folgende Scriptanwendung wird über den Windows Scheduler jede Minute gestartet und abgearbeitet.
Wenn ich in das zu überwachende Verzeichnis Tesdateien kopiere, funktioniert alles einwandfrei.
Werden aber über eine entsprechende Applikation Dateien in das Verzeichnis geschrieben, hängt sich das Script oder der Scheduler auf.
Diese muss ich dann immer manuell stoppen und neu starten.
Eine Vermutung habe ich noch:
Kann es sein, wenn die Applikation Dateien schreibt, und dafür, ich sage mal 5 Minuten für eine Datei braucht,
die neue Datei gesperrt ist. Mein Script sich aber hier schon eine Variable merkt, mit dieser aber nichts anfangen kann und
sich so aufhängt.
Vielen Dank im Voraus für eine Idee.
Nun das besagt Script:
rem ////////////////////////////////////////////////
set counter=0
set maxcount=10
:start
rem Etiketten und Chechire
set "Pfad=C:\Streamserve\spoolcitrix\AboOut00*.*"
if not exist C:\Streamserve\\spoolcitrix\AboOut00*.* goto Palettenleitzettel
for /f "delims=" %%i in ('echo %Pfad%') do set "varib=%%~nxi"
copy C:\Streamserve\spoolcitrix\%varib% \\sedemune0044\Streamserve\save\Adware\raw
:warten1
if not exist "\\sedemune0044\Streamserve\save\Adware\raw\%varib%" goto warten1
move c:\Streamserve\spoolcitrix\%varib% \\sedemune0044\Streamserve\Print\Adware\Versandunterlagen
:Palettenleitzettel
rem Palettenleitzettel
set "Pfad=C:\Streamserve\spoolcitrix\AboZePlt*.*"
if not exist C:\Streamserve\\spoolcitrix\AboZePlt*.* goto Bundzettel
for /f "delims=" %%i in ('echo %Pfad%') do set "varib=%%~nxi"
copy C:\Streamserve\spoolcitrix\%varib% \\sedemune0044\Streamserve\save\Adware\raw
:warten2
if not exist "\\sedemune0044\Streamserve\save\Adware\raw\%varib%" goto warten2
move C:\Streamserve\spoolcitrix\%varib% \\sedemune0044\Streamserve\Print\Adware\Versandunterlagen
:Bundzettel
rem Bundzettel
set "Pfad=C:\Streamserve\spoolcitrix\AboZeBnd*.*"
if not exist C:\Streamserve\\spoolcitrix\AboZeBnd*.* goto Ende
for /f "delims=" %%i in ('echo %Pfad%') do set "varib=%%~nxi"
copy C:\Streamserve\spoolcitrix\%varib% \\sedemune0044\Streamserve\save\Adware\raw
:warten3
if not exist "\\sedemune0044\Streamserve\save\Adware\raw\%varib%" goto warten3
move C:\Streamserve\spoolcitrix\%varib% \\sedemune0044\Streamserve\Print\Adware\Versandunterlagen
:Ende
set /a counter=%counter% + 1
if "%counter%" NEQ "%maxcount%" goto start
echo Filemove_Versandunterlagen_SpoolCitrix_to_Print.bat gelaufen am %date% um %time% >> c:\Batch\Spoolcitrix.txt 2>&1
exit
rem ////////////////////////////////////////////////
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 130848
Url: https://administrator.de/contentid/130848
Ausgedruckt am: 15.11.2024 um 13:11 Uhr
18 Kommentare
Neuester Kommentar
Ich habe die Batch jetzt nicht so genau durchgeschaut, aber es kann schon dran liegen das du die datei die gerade noch geschrieben wird verschieben willst.
Um das zu testen kannst du ja mal einfach die Zeit von 1 auf z.B. 5 Minuten erhöhen und sehen ob es daran liegt.
Ist das der Fall kannst du eine Kontrolle im z.B. 4 Sekunden Abstand einbauen die immer wieder die Änderungszeit der Datei kontrolliert. Hat sich die Änderungszeit in den letzten 4 sekunden nicht verändert kann die Datei weiter verarbeitet werden.
Um das zu testen kannst du ja mal einfach die Zeit von 1 auf z.B. 5 Minuten erhöhen und sehen ob es daran liegt.
Ist das der Fall kannst du eine Kontrolle im z.B. 4 Sekunden Abstand einbauen die immer wieder die Änderungszeit der Datei kontrolliert. Hat sich die Änderungszeit in den letzten 4 sekunden nicht verändert kann die Datei weiter verarbeitet werden.
Moin KeiosID,
mir geht es ähnlich wie miniversum... ich schaffe es auch gar nicht, die Batch bis zum Ende zu lesen, weil ich vorher schon über Sachen stolpere, die -wie der Franzose sagt- unpredictable results erzeugen könnten und sicherlich so gar nicht bewusst da implementiert werden sollten.
Abgebrochen mit dem Lesen habe ich am Ende des ":start"-Blocks (Zeilen 08-11)
Das kann nicht so gewollt sein.
0) Eine Anweisung "Setlocal" sollte ganz oben rein - gerade wenn es sein kann, dass mehrere Batchinstanzen zeitgleich laufen und est recht, wenn es nicht stabil läuft und manche davon endlos kreisen und/oder abgebrochen werden müssen.
1) Die Anweisung [set "Pfad=C:\Streamserve\spoolcitrix\AboZePlt*.*"] gilt für den gesamten Batch und gehört damit auch nach ganz oben.
2) Wenn es die Variable "%Pfad%" gibt, dann muss sie auch hier benutzt werden: [if not exist C:\Streamserve\\spoolcitrix\AboOut00*.* goto Palettenleitzettel ]
3) Die Zeile hier ist nicht richtig...hier hast du ein Zufallsergebnis [for /f "delims=" %%i in ('echo %Pfad%') do set "varib=%%~nxi"]
4) Die Zeile [copy C:\Streamserve\spoolcitrix\%varib% \\sedemune0044\Streamserve\save\Adware\raw ] unmittelbar danach macht zwar dann alles, was sie soll, ist aber auf die marode Zeile davor angewiesen. Wenn in der FOR-Anweisungszeile KEINE Variable %varib% neu gesetzt wird, dann rennt diese Zeile halt mit dem %variab%-Wert der Vorrunde nochmal im Kreis ...
Die marode Zeile [for /f "delims=" %%i in ('echo %Pfad%') do set "varib=%%~nxi" ] nehme ich mal gesondert auseinander.
Wenn ich an meinem heimischen CMD-prompt spiele und das auf meine dateien "E:\Dokus\*.PDF" anwende (wo ein paar Dutzend *.pdfs liegen, dann kömmt herum:
[das ">" nicht mit eingeben - ist mein Prompt]
---> d.h. auch wenn sich 27000 *.pdf-Dateien in dem Verzeichnis habe, wird immer nur "die erste" (nach welchen Kriterien auch immer sortiert) gefunden.
Dafür bräuchte ich keine FOR-Anweisung... und außerdem erst recht keine "FOR /F "delims"-Special-Edition, sondern eine einfache FOR %i Anweisung.
Also würde ich zumindest diese Böcke rausschmeißeb und dann weiterfahnden:
Weiter lohnt es sich IMHO noch nicht, nach Fehlern zu suchen (könnten alles Folgefehler sein).
Grüße
Biber
mir geht es ähnlich wie miniversum... ich schaffe es auch gar nicht, die Batch bis zum Ende zu lesen, weil ich vorher schon über Sachen stolpere, die -wie der Franzose sagt- unpredictable results erzeugen könnten und sicherlich so gar nicht bewusst da implementiert werden sollten.
Abgebrochen mit dem Lesen habe ich am Ende des ":start"-Blocks (Zeilen 08-11)
Das kann nicht so gewollt sein.
....
set "Pfad=C:\Streamserve\spoolcitrix\AboZePlt*.*"
if not exist C:\Streamserve\\spoolcitrix\AboOut00*.* goto Palettenleitzettel
for /f "delims=" %%i in ('echo %Pfad%') do set "varib=%%~nxi"
copy C:\Streamserve\spoolcitrix\%varib% \\sedemune0044\Streamserve\save\Adware\raw
...
0) Eine Anweisung "Setlocal" sollte ganz oben rein - gerade wenn es sein kann, dass mehrere Batchinstanzen zeitgleich laufen und est recht, wenn es nicht stabil läuft und manche davon endlos kreisen und/oder abgebrochen werden müssen.
1) Die Anweisung [set "Pfad=C:\Streamserve\spoolcitrix\AboZePlt*.*"] gilt für den gesamten Batch und gehört damit auch nach ganz oben.
2) Wenn es die Variable "%Pfad%" gibt, dann muss sie auch hier benutzt werden: [if not exist C:\Streamserve\\spoolcitrix\AboOut00*.* goto Palettenleitzettel ]
3) Die Zeile hier ist nicht richtig...hier hast du ein Zufallsergebnis [for /f "delims=" %%i in ('echo %Pfad%') do set "varib=%%~nxi"]
4) Die Zeile [copy C:\Streamserve\spoolcitrix\%varib% \\sedemune0044\Streamserve\save\Adware\raw ] unmittelbar danach macht zwar dann alles, was sie soll, ist aber auf die marode Zeile davor angewiesen. Wenn in der FOR-Anweisungszeile KEINE Variable %varib% neu gesetzt wird, dann rennt diese Zeile halt mit dem %variab%-Wert der Vorrunde nochmal im Kreis ...
Die marode Zeile [for /f "delims=" %%i in ('echo %Pfad%') do set "varib=%%~nxi" ] nehme ich mal gesondert auseinander.
Wenn ich an meinem heimischen CMD-prompt spiele und das auf meine dateien "E:\Dokus\*.PDF" anwende (wo ein paar Dutzend *.pdfs liegen, dann kömmt herum:
[das ">" nicht mit eingeben - ist mein Prompt]
>set "Var=e:\dokus\*.pdf"
(=13:13:57 D:\temp=)
>for /f "delims=" %i in ("%var%") do @echo set "varib=%~nxi"
set "varib=VB_Puzzlebuch.pdf"
##oder gleichbedeutend, nur umständlicher wie oben
(=13:14:16 D:\temp=)
>for /f "delims=" %i in ('echo "%var%"') do @echo set "varib=%~nxi"
set "varib=VB_Puzzlebuch.pdf"
Dafür bräuchte ich keine FOR-Anweisung... und außerdem erst recht keine "FOR /F "delims"-Special-Edition, sondern eine einfache FOR %i Anweisung.
> FOR %i in ("%var%") do Echo whatever with "%~nxi"
Also würde ich zumindest diese Böcke rausschmeißeb und dann weiterfahnden:
...
Setlocal
...
Set ... (counter etc wie oben)
set "Pfad=C:\Streamserve\spoolcitrix\AboZePlt*.*"
:Start
if not exist "%pfad%" goto Palettenleitzettel
for %%i in ("%Pfad%") do (
copy "%%i" "\\sedemune0044\Streamserve\save\Adware\raw\%%~nxi"
)
......
Weiter lohnt es sich IMHO noch nicht, nach Fehlern zu suchen (könnten alles Folgefehler sein).
Grüße
Biber
Moin KeiosID,
sorry für die späte Antwort - hatte nicht die nötige Muße für dein Problem.
Aber nochmal - das Problem, das ich in meinem ersten Kommentar ausschliessen wollte ist jetzt wieder/immer noch im Sourcecode.
In deinen jetzt geposteten Zeilen 13/14/15 passiert nicht das, was du beabsichtigst.
Die erste dieser Zeilen [FOR %%i in (AlleDateienXY) Do set "varibA=EineVonAllenDateienXY" ] rödelt wirklich durch alle vorhandenen 187 Dateien durch.
Am Ende des Tages bzw. am Ende der Zeile hast Du dann aber nur den Namen der 187sten Datei, des letzten Elements diser Liste in der Variablen %varibA%.
Und auch nur auf diese eine einzige Datei werden die beiden nachfolgenden Anweisungen angewandt.
!! Bitte ändere diesen Abschnitt möglichst mit dem Ziel, dass die Variable %varibA% ganz wegfällt.
Grüße
Biber
sorry für die späte Antwort - hatte nicht die nötige Muße für dein Problem.
Aber nochmal - das Problem, das ich in meinem ersten Kommentar ausschliessen wollte ist jetzt wieder/immer noch im Sourcecode.
In deinen jetzt geposteten Zeilen 13/14/15 passiert nicht das, was du beabsichtigst.
...
for %%i in ("%PfadA%") do set "varibA=%%~nxi"
echo "%varibA%"
copy "%Pfad%\%variabA%" "%Pfadraw%"
....
Die erste dieser Zeilen [FOR %%i in (AlleDateienXY) Do set "varibA=EineVonAllenDateienXY" ] rödelt wirklich durch alle vorhandenen 187 Dateien durch.
Am Ende des Tages bzw. am Ende der Zeile hast Du dann aber nur den Namen der 187sten Datei, des letzten Elements diser Liste in der Variablen %varibA%.
Und auch nur auf diese eine einzige Datei werden die beiden nachfolgenden Anweisungen angewandt.
!! Bitte ändere diesen Abschnitt möglichst mit dem Ziel, dass die Variable %varibA% ganz wegfällt.
...
for %%i in ("%PfadA%") do (
echo Bearbeite Datei %%~nxi
copy "%Pfad%\%%~nxi" "%Pfadraw%"
)
...
Grüße
Biber
Moin keiosID,
Und diesen Fall kannst in der Zeile nach dem COPY ja prüfen mit "IF ERRORLEVEL 1 goto :tryAgain" und ":tryAgain" vor den COPY-Befehl setzen.
Wenn die Datei sich COPYren liess, dann kann der MOVE danach ja keine Probleme mehr haben. Eigentlich...
Grüße
Biber
Zitat von @KeiosID:
1. Was passiert, wenn die Datei, die gerade kopiert wird eine größere Datei ist, sagen wir mal 150Mb?
Wartet hier dann das cmd von alleine, bis der Kopiervorgan fertig ist und arbeitet dann erst den move ab?
Ja..1. Was passiert, wenn die Datei, die gerade kopiert wird eine größere Datei ist, sagen wir mal 150Mb?
Wartet hier dann das cmd von alleine, bis der Kopiervorgan fertig ist und arbeitet dann erst den move ab?
1.1. Was passiert wenn es mehrer Dateien mit dem Typ AboOut00*.txt gibt.(kommt vor)
Dann dauerts mal wieder ein wenig länger.2. Was passiert, wenn die Datei noch von der Applikation im Zugriff ist?
Genauer, die Datei wird geschrieben und wächst solange, bis diese fertig ist.
Wenn die Datei hoch von einer anderen Appz im exklusiven Zugriff gehalten wird, dann lässt sich nicht ohne Fehler kopieren.Genauer, die Datei wird geschrieben und wächst solange, bis diese fertig ist.
Und diesen Fall kannst in der Zeile nach dem COPY ja prüfen mit "IF ERRORLEVEL 1 goto :tryAgain" und ":tryAgain" vor den COPY-Befehl setzen.
Wenn die Datei sich COPYren liess, dann kann der MOVE danach ja keine Probleme mehr haben. Eigentlich...
3. Kann ich hier nun das analog für andere Dateitypen kopiern und anpassen?
Kannst Du mir ein anderes Beispiel für rhetorische Fragen geben?Danke im Voraus
Dafür nich'.Gruß Keios
Grüße
Biber
Moin KeiosID,
Und scheint zu tun, was ein Skript halt so tun soll.
Noch ein, zwei kosmetische Änderungsvorschläge:
--> Ich habe "nur" an die Befehlszeilen COPY und MOVE ein ">nul" angehängt, damit die (kein-Fehler-)Meldung "1 file(s) copied/moved" nicht erscheint.
--> denn wenn überhaupt interessiert mich ja nicht die Nicht-Fehlerfall-Meldung, sondern höchstens die Fehlerfallmeldung ("File in use by another DAU" o.ä.)
--> Achtung!! --a) wenn das COPY nicht klappt, macht der Batch ein "tryAgain" bis Weihnachten. Genauer gesagt bis Weihnachten 2199.
--> Achtung!! --b) wenn das MOVE nicht klappt, ignoriere ich das (keine Fehlerbehandlung). Weil.... weil ich sage, einen Fehler an dieser Stelle schließe ich aus.(Siehe "Das Telekom-Prinzip" oder "Regierungserklärung Merkel" ) Da passiert halt per definitione nichts Abweichendes von meinem Plan
Falls ich dich verwirrt habe nochmal zusammengefasst:
Grüße
Biber
wird das script nun Korrekt abgearbeitet ?
Ich sag mal so, zumindest würde ich sagen Works as designed.Und scheint zu tun, was ein Skript halt so tun soll.
Noch ein, zwei kosmetische Änderungsvorschläge:
@echo off & setlocal
:: .... variablen-Initialisierung etc..
pause pause1
rem Etiketten und Chechire
if not exist "%PfadA%" goto Palettenleitzettel
pause pause1.1
for %%i in ("%PfadA%") do (
echo Bearbeite Datei fuer copy %%~nxi
:tryAgain
copy "%Pfad%\%%~nxi" "%Pfadraw%" >nul ||goto :tryAgain
echo Bearbeite Datei fuer move %%~nxi
move "%Pfad%\%%~nxi" "%Pfadprint%" >nul
)
pause pause2
--> Ich habe "nur" an die Befehlszeilen COPY und MOVE ein ">nul" angehängt, damit die (kein-Fehler-)Meldung "1 file(s) copied/moved" nicht erscheint.
--> denn wenn überhaupt interessiert mich ja nicht die Nicht-Fehlerfall-Meldung, sondern höchstens die Fehlerfallmeldung ("File in use by another DAU" o.ä.)
--> Achtung!! --b) wenn das MOVE nicht klappt, ignoriere ich das (keine Fehlerbehandlung). Weil.... weil ich sage, einen Fehler an dieser Stelle schließe ich aus.(Siehe "Das Telekom-Prinzip" oder "Regierungserklärung Merkel" ) Da passiert halt per definitione nichts Abweichendes von meinem Plan
Falls ich dich verwirrt habe nochmal zusammengefasst:
- sieht so aus, als würde der Schnipsel jetzt das machen, was er soll
- zwei Annahmen sind implementiert, die nicht verifiziert sind: a) Ein COPY-Fehler tritt immer nur temporär auf und b) ein MOVE geht immer
- Die beiden letzten Annahmen würde ich "im Auge behalten", aber dennoch den Schnipsel so einsetzen.
- Von daher könntest du aus meiner Sicht noch heute ein Häkchen in der Farbe eines hinter die Spüle gefallenen Kaffee-Pads setzen
Grüße
Biber
Moin KeiosID,
also...
Sonst sehe ich mit bloßem Auge nichts -- gibt/gab es denn irgendwelche FehlerMELDUNGEN?
Grüße
Biber
also...
- ich gehe davon aus, dass die "**" nach "Etiketten" (Zeile 20) und rund um ":Palettenleitzettel" nur Formatierungsversuche, aber nicht im tatsächlichen Code enthalten sind? Falls doch im Code, dann ist es ebensolcher. Dann bitte ändern.
- ich sehe keinen Vorteil, bei einem "COPY-Fehler" nochmal so weit zurückzugehen bzw. die ganze FOR %%i in (dateien)-Anweisung nochmal neu zu starten. Aber okay - würde auch nix kaputtmachen
- was allerdings wohl nicht klappen wird (soweit habe ich beim ersten Mal ja gar nicht gelesen wegen der angesprochenen Bugs)- der MOVE.Befehl kann (zumindest unter XP und früher) NUR auf demselben Laufwerk verschieben. Ein MOVE von C:\bla\x.y nach C:\Blubb ist okay; ein MOVE von c:\bla\x.y nach D:\blubb oder \\server\blabb geht nicht. Hier müsstest du den "logischen MOVE" selbst machen durch ein "COPY c:\bla\x.y D:\blubb" und anschliessendes "Del c:\Blubb\x.y".
Sonst sehe ich mit bloßem Auge nichts -- gibt/gab es denn irgendwelche FehlerMELDUNGEN?
Grüße
Biber