Batch: Aktiver auf Variablen basierter Ladebalken, help?
Ich versuche gerade mithilfe von BATCH bzw. CMD eine Sicherung zu entwickeln die mehrere Instanzen von kopiervorgängen öffnet die alle gleichzeitig arbeiten. Der klu an der Sache ist, ich möchte auch einen lade Balken der pro fertig gewordenen Vorgang hochzählt bis alle zusammen sind und dann einem Bescheid das er fertig ist.
Bisher habe ich es so versucht:
Mein Zähler:
@echo off
set TRUEcounter=0
set FALSEcounter=0
:start
if exist "TEMP\TRUE" goto true
if exist "TEMP\FALSE.txt" goto false
rem Das Laufwerk wird automatisch das genommen wo auch diese .cmd ist.
if %TRUEcounter%=18 goto exit
timeout /t 1
goto start
:true
rename "%x%\TEMP\TRUE" "!true"
set /a TRUEcounter=%TRUEcounter%+1
goto start
:false
rename "%x%\TEMP\FALSE" "!false"
set /a FALSEcounter=%FALSEcounter%+1
goto start
:exit
set TRUEcounter=0
set FALSEcounter=0
exit
Der Ladebalken:
@echo off
set TRUEcounter=0
set FALSEcounter=0
color 0a
mode con cols=100 lines=28
:0/18
LOGO
LADEBALKEN
echo Fehler: %FALSEcounter%
:00
if "%TRUEcounter%"=="1" goto 1/18
rem frühere Idee (if %TRUEcounter%==>1 goto 1/18 UND if %TRUEcounter%==0)
timeout /t 1 >NUL
goto 00
:1/18
cls
echo Fehler: %FALSEcounter%
:01
if "%TRUEcounter%"="2" goto 2/18
rem if TRUEcounter>1 goto 2/18
timeout /t 1
goto 01
und so weiter
1 Antwort
Entschuldige mir ist es gerade eiskalt den Rücken runtergelaufen.
die mehrere Instanzen von kopiervorgängen öffnet die alle gleichzeitig arbeiten
Wenn 8 physisch Laufwerke in/an deinem Rechnergehäuse stecken wären 4 parallele Kopiervorgänge vielleicht noch plausibel. Auf einem oder zwischen 2 Datenträgern (evtl sogar noch über USB) sind parallele Kopiervorgänge sogar kontraproduktiv.
Das langsamste am kopieren ist nicht das Kopierprogramm sondern der Datenträger. (Das cachen von Schreibvorgängen durch das System kann bei kleinen Dateien lediglich eine höhere Geschwindigkeit suggerieren)
Bei Festplatten als Sicherungslaufwerk führen parallele Schreibvorgänge zu starker Datenfragmentierung und einer extremen Belastung der Mechanik. (beides für ein Sicherungslaufwerk ein absolutes NoGo!.
...Das erstmal zum rein Physischen.
CMD eine Sicherung zu entwickeln
In Batch entwickelt man nichts... sondern ein Systemadministrator automatisiert damit wiederkehrende Abläufe. Wobei Automatisch auch selbiges bedeutet... man kümmert sich nicht mehr darum... und es genügt wenn die Batch eine Fertigmeldung rapportiert.
Batch hat nur eingeschränkte Möglichkeiten zur Parallisierung von Prozessen. Der start-Befehl (ohne /wait) ist das einzige Kommando welches Prozesse parallel ausführen kann. Damit verliert die aufrufende Batch jedoch die Kontrolle über den aufgerufenen Prozess und kann von diesem im Normalfall auch keine Daten empfangen.
Natürlich kann man leicht festellen ob ein derart gestarteter Prozess noch läuft.
demo.cmd
@echo off
chcp 65001 >nul
setlocal enableDelayedExpansion
set "WindowName=Hauptprozess"
set "self=%~f0"
if "%~1"=="sub" goto :subProcess
:main
rem starte numerierte Supprozesse
set "SubwindowName=MeinSubprozess"
rem starte 10 asynchrone Subprozesse
for /l %%a in (1,1,10) do (
rem zufall für die Demolaufzeiten mitgeben 10 bis 30 Sekunden
set /a "RandomTimer=!random! %% (30-10+1) +10"
rem starte minimiert
start "%SubwindowName% %%a" /min cmd /c "%self%" sub !RandomTimer!
)
set OldCount=10
rem zwischen :loop und :loopEnd darf nichts außer '<nul set /p "=*"' schreiben!!! (mit ESC-sequenzen wäre das etwas anders)
:loop
timeout 1 >nul &rem eine sekunde warten
rem feststellen wieviele der subprozesse noch laufen
for /f "tokens=* delims=[]" %%a in ('tasklist /nh /fi "WindowTitle eq %SubwindowName%*"^|find /c "cmd"') do (set "NewCount=%%a")
if %NewCount% equ 0 goto :loopEnd
if %NewCount% lss %OldCount% (
rem ganz Primitiver Fortschrittsbalken
<nul set /p "=*"|| (call )
set "OldCount=%NewCount%"
)
goto :loop
:loopEnd
echo fertig
pause
exit /b
:subProcess
rem hier käme rein was jeweils Parallel passiern soll
rem zur Demo einfach ein Timeout
timeout %2
exit /b
Was den hier verwendeten Fortschrittsbalken findest Du mehr unter: https://www.gutefrage.net/frage/ladeblken-mit-batch-pogramm-erstellen#answer-373989384
Letztlich ist das Ganze lediglich eine Spielerei.
Was Deine Syntax angeht , so habe ich garnicht erst versucht zu ergründen, was Dein Code da tut. Dieser strotzt nur so vor Fehlern und "schlechtem Stil"
auch wenn Batch es klaglos hinnimmt:
- niemals Sprunglabeln Namen wie true , false , exit oderBehlsnamen usw. geben.
- niemals Zahlen am Beginn von Labeln und auch keine Sonderzeichen oder mathematischen Operatoren verwenden.
- Ausrufezeichen in Datei- oder Variablennamen absolut vermeiden, das Ausrufezeichen hat unter gewissen Bedingungen in Batch eine Spezialfunktion. Mit einer Batch, wie der obigen wäre der Zugriff solche Dateien umständlich.
Fehler:
- IF falsche vergleichsoperatoren
- zugriff auf nicht existierende Ordner (immer sicherstellen, das Ordner, in welchen Du oder jemand anderes agieren soll, auch existieren. Eine Zeile : md "pfad" 2>nul (heist erstelle Ordner falls dieser nicht existiert)
Batch oberhalb einfacher Befehlsabfolgen ist eine der schwierigsten Sprachen, welche es überhaupt gibt. Ich mache das als Herausforderung, wie andere ein Kreuzworträtsel oder Sudoku lösen . Normalerweise Programmiere ich in anderen Sprachen.
Einem Anfänger wie Dir würde ich empfehlen besser Powershell als Scriptsprache zu lernen.
Wenn Du richtige Anwendungen programmieren möchtest, lerne C#
Solltest Du noch immer der Ansicht sein, das es lohnenswert sei sich mit den alten Monster zu quälen, schau die Rubrik batch-trick durch, da findest Dur reichlich Beispiele für den Umgang damit dem Biest.