copworker
Goto Top

Batch File Variable überschreiben

Hallo zusammen,

in meinem Batch File ist eine Problem was ich nicht verstehe.
Vor ab, ich komme aus der C/C++/C# Welt.

Mein Batch File soll sequenziell nacheinander mehrere Dateien aus verschiedenen Verzeichnissen kopieren.
Vor jeder Kopieranweisung stelle ich dem User die Frage ob er den Kopiervorgang starten will oder nicht.
Betätigt der User die Enter-Taste ohne zuvor eine Eingabe gemacht zu haben, bleibt der Wert der Variablen "JESNO" erhalten.
Wie mache ich das, dass die Variable "JESNO" bei keiner Eingabe keinen Inhalt hat bzw. den Inhalt löscht?
Oder wie kann ich den vorhandenen Text zuvor entfernen.
set JESNO= funktioniert auch nicht.
set JESNO="" ist doch falsch, oder?

Die betroffenen Stellen sind rot gekennzeichnet.

Hier der gesamte Inhalt des Batch Files

@echo off
color 1F
title CheckOut
echo Dies Anwendung erstellt selektierte Kopien der lokalen Arbeitsumgebung auf das benutzerbezogene Konto

:PASSWORD
set /p PWD=Bitte Passwort eingeben:
if [%PWD%] == echo Es konnte keine Eingabe erkannt werden && goto PASSWORD
echo.
echo Danke %PWD%
if not %PWD% == Super echo Keine Berechtigung fuer einen CheckOut && goto END
echo.

set nameFolder=Arbeitshilfen
set nameFolder[1]=Intern
set nameFolder[2]=Projekte
set nameFolder[3]=Control
set pathRootLocal=C:\Users\schwer-robert\AppData\Local\Workspace
set pathRootRemote=H:\Vertraulich\Workspace

:WORKHELP
echo WORKHELP
set pathSource=%pathRootLocal%\%nameFolder%
set pathTarget=%pathRootRemote%\%nameFolder%
echo Sollen die Inhalte von "%nameFolder%" auf persoenliches Laufwerk kopiert werden?
set /p JESNO=Auswahl (Ja/Nein/Exit) Eingabe hier:
echo.

if [%JESNO%] == echo Es konnte keine Eingabe erkannt werden && goto WORKHELP
if %JESNO% == Exit goto EXIT
if not %JESNO% == Ja goto INTERNAL
echo Mit "Enter" werden die Dateien kopiert.
echo Quelle: %pathSource%
echo Ziel: %pathTarget%
pause >NUL
copy %pathSource%\*.* %pathTarget%

:INTERNAL
echo INTERNAL
set pathSource=%pathRootLocal%\%nameFolder[1]%
set pathTarget=%pathRootRemote%\%nameFolder[1]%
echo Sollen die Inhalte von "%nameFolder[1]%" auf persoenliches Laufwerk kopiert werden?
set /p JESNO=Auswahl (Ja/Nein/Exit) Eingabe hier:
echo.

if [%JESNO%] == echo Es konnte keine Eingabe erkannt werden && goto INTERNAL
if %JESNO% == Exit goto EXIT
if not %JESNO% == Ja goto PROJECTS
echo Mit "Enter" werden die Dateien kopiert.
echo Quelle: %pathSource%
echo Ziel: %pathTarget%
pause >NUL
copy %pathSource%\*.* %pathTarget%


:PROJECTS
echo PROJECTS
set pathSource=%pathRootLocal%\%nameFolder[2]%
set pathTarget=%pathRootRemote%\%nameFolder[2]%
echo Sollen die Inhalte von "%nameFolder[2]%" auf persoenliches Laufwerk kopiert werden?
set /p JESNO=Auswahl (Ja/Nein/Exit) Eingabe hier:
echo.

if [%JESNO%] == echo Es konnte keine Eingabe erkannt werden && goto PROJECTS
if %JESNO% == Exit goto EXIT
if not %JESNO% == Ja goto CONTROL
echo Mit "Enter" werden die Dateien kopiert.
echo Quelle: %pathSource%
echo Ziel: %pathTarget%
pause >NUL
copy %pathSource%\*.* %pathTarget%
pause >NUL


:CONTROL
echo CONTROL
set pathSource=%pathRootLocal%\%nameFolder[3]%
set pathTarget=%pathRootRemote%\%nameFolder[3]%
echo Sollen die Inhalte von "%nameFolder[3]%" auf persoenliches Laufwerk kopiert werden?
set /p JESNO=Auswahl (Ja/Nein/Exit) Eingabe hier:
echo.

if [%JESNO%] == echo Es konnte keine Eingabe erkannt werden && goto CONTROL
if %JESNO% == Exit goto EXIT
if not %JESNO% == Ja goto END
echo Mit "Enter" werden die Dateien kopiert.
echo Quelle: %pathSource%
echo Ziel: %pathTarget%
pause >NUL
copy %pathSource%\*.* %pathTarget%
pause >NUL


:END
echo END
echo Sollen die Anwenung beendet werden?
set /p EXIT=Mit der Eingabe von "Exit" wird die Anwendung beendet:
echo.
if %EXIT% == Exit goto EXIT
if %EXIT% == Ja goto EXIT
if %EXIT% == Ende goto EXIT


pause >NUL
cls && goto PASSWORD

:EXIT
echo Die Anwendung wird beendet
ping localhost -n 2 > NUL
pause

Vielen Dank.
Vielen Grüße von CopWorker

Content-Key: 597462

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

Printed on: June 27, 2024 at 02:06 o'clock

Member: Shadowminder
Shadowminder Aug 19, 2020 at 13:21:01 (UTC)
Goto Top
Zitat von @CopWorker:
set JESNO= funktioniert auch nicht.
set JESNO="" ist doch falsch, oder?

Hallo @CopWorker,

set JESNO="" ist richtig

LG Shadowmind
Member: TK1987
TK1987 Aug 19, 2020 updated at 13:25:30 (UTC)
Goto Top
Moin,

Zitat von @CopWorker:
Vor ab, ich komme aus der C/C++/C# Welt.
Warum tust du dir dann Batch an, statt zeitgemäß auf Powershell zu setzen?

Sei's drum. Für dein Vorhaben ist choice eigentlich die bessere Wahl. Zum einen kann der Benutzer dann keine leere Eingabe mehr tätigen, da nur noch die Tasten "J" & "N" zulässig sind, zum anderen ist so auch keine falsche Eingabe mehr möglich.

echo.Moechten Sie fortfahren?
choice
if "%errorlevel%" equ "1" echo.Benutzer hat Ja gewaehlt  
if "%errorlevel%" equ "2" echo.Benutzer hat Nein gewaehlt  

Gruß Thomas
Member: rubberman
rubberman Aug 19, 2020 at 15:40:55 (UTC)
Goto Top
Zitat von @Shadowminder:
set JESNO="" ist richtig

Nein dann hat die Variable den Wert "", also 2 Anführungszeichen als Text.

:CONTROL

REM nach dieser Anweisung ist die Umgebungsvariable nicht definiert.
set "JESNO="  
...
set /p ...

REM Hier wird geprüft ob die Variable noch immer nicht definiert ist, also der User ohne weitere Eingabe Enter gedrückt hat.
if not defined YESNO goto CONTROL

Alles immer noch komplett inkonsistenter Mist in Batch. Um das narrensicher zu machen ist viel mehr notwendig. Sollte der User ein einzelnes Anführungszeichen eingeben geht das trotzdem krachen.

Steffen
Member: erikro
Solution erikro Aug 19, 2020 at 20:28:20 (UTC)
Goto Top
Moin,

Zitat von @TK1987:

Moin,

Zitat von @CopWorker:
Vor ab, ich komme aus der C/C++/C# Welt.
Warum tust du dir dann Batch an, statt zeitgemäß auf Powershell zu setzen?

Ohja. Wenn ich dieses ganze if-goto angucke, wird mir ganz schwindelig. face-wink

$dirs = @("Arbeitshilfen","Intern","Projekte","Projekte","Control")  
$path_local = "$env:USERPROFILE\AppData\Local\Workspace"  
$path_remote = "H:\Vertraulich\$env:username"  
foreach ($dir in $dirs) {

    copy-item -Path "$path_local\$dir" -Destination "$path_remote\$dir" -Recurse -Force -Confirm  

}

So sähe das in etwa in der PS aus. (Nicht getestet.)

Und was mich wirklich interessieren würde: Was soll dass denn?
:PASSWORD
set /p PWD=Bitte Passwort eingeben:
if [%PWD%] ==  echo Es konnte keine Eingabe erkannt werden && goto PASSWORD
echo.
echo Danke %PWD%
if not %PWD% == Super echo Keine Berechtigung fuer einen CheckOut && goto END
echo.

Super Passwortabfrage. Tolles Passwort. face-wink Richtig schick ist aber, dass Du das dann auch noch im Klartext ausgibst. face-wink

Und noch eine Frage: Was machen solche Daten überhaupt im Userprofil. Sowas gehört auf den Server. Außerdem lässt man solche Kopien nicht die User machen, sondern das passiert automatisiert auf extra Datenträgern. Auch bekannt unter Backup. face-wink

Liebe Grüße

Erik
Member: CopWorker
CopWorker Aug 20, 2020 at 06:12:15 (UTC)
Goto Top
Hallo an alle,

erstmal bin ich überrascht, dass ich so viel Hilfe erhalten habe.
Das verstehe ich auch alles.
Die Anwendung soll nur aus verschiedenen Verzeichnissen die Verknüpfungen
zu Programmen, Projekten, Internet-Seiten, usw. auf ein persönliches Netzlaufwerk kopieren.
Die Entscheidung ob das geschehen soll oder nicht ist jedem Angestellten selber überlassen.

@erikro:
Die Arbeit ist noch nicht fertig. Ich muss das alles erst mal lernen.
Das mit dem Passwort weiß ich noch nicht wie man einzelne Zeichen durch '*' ersetzt bevor man diese auf der Konsole ausgibt.
Wenn du´s mir verrätst, das wäre fein.

Und vielen Dank nochmal an alle.
Grüße von CopWorker
Member: CopWorker
CopWorker Aug 20, 2020 at 06:16:12 (UTC)
Goto Top
Hallo TK1987, Thomas,

das mit choice hatte ich auch schon drin.
Doch leider muss es auch möglich sein mit der Eingabe von Exit
ganz aus dem Vorgang auszusteigen um das Ganze zu beenden.

Trotzdem vielen Dank.
Grüße von CopWorker
Member: TK1987
TK1987 Aug 20, 2020 at 13:34:39 (UTC)
Goto Top
Zitat von @CopWorker:
Doch leider muss es auch möglich sein mit der Eingabe von Exit
ganz aus dem Vorgang auszusteigen um das Ganze zu beenden.
Auch das wäre kein Problem. Man kann bei Choice ja mit Schalter /c beliebig viele Optionen angeben.
echo.Moechten Sie fortfahren?  [J]a / [N]ein / [E]xit
choice /c jne
if "%errorlevel%" equ "1" echo.Benutzer hat Ja gewaehlt  
if "%errorlevel%" equ "2" echo.Benutzer hat Nein gewaehlt  
if "%errorlevel%" equ "3" goto :EoF  
Member: erikro
erikro Aug 21, 2020 at 12:21:32 (UTC)
Goto Top
Moin,

Zitat von @CopWorker:
erstmal bin ich überrascht, dass ich so viel Hilfe erhalten habe.

So sind wir. face-wink

@erikro:
Die Arbeit ist noch nicht fertig. Ich muss das alles erst mal lernen.

Dann lerne Powershell und lass das mit den Batches. Batch-Programmierung war schon immer gruselig. Du siehst ja an meinem Beispiel, mit wie wenigen Zeilen und schön übersichtlich das in der PS aussieht. face-wink Und wenn Du von C kommst, wird Dir die PS auch gut gefallen.

Das mit dem Passwort weiß ich noch nicht wie man einzelne Zeichen durch '*' ersetzt bevor man diese auf der Konsole ausgibt.
Wenn du´s mir verrätst, das wäre fein.

AFAIK in Batches gar nicht. face-wink Ich würde das mit dem PW eh lassen. Leg das Skript irgendwo ab, wo nur User darauf Zugriff haben, die das sowieso dürfen.

Noch ein Hinweis: PS-Skripts sind im Standard verboten. Stichwort: set-executionpolicy. Ich würde es für User nur mit signierten Skripts freigeben.

Liebe Grüße

Erik
Mitglied: 145033
145033 Aug 21, 2020 updated at 13:24:52 (UTC)
Goto Top
Zitat von @erikro:
AFAIK in Batches gar nicht. face-wink
Wenn man die PS auch wieder zur Hilfe nimmt dann geht auch das wenn man unbedingt will
@echo off
for /f "delims=" %%a in ('powershell -EP Bypass -C "[System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR((Read-host 'Passwort eingeben' -AsSecureString)))"') do set "pass=%%a"  
echo %pass%
Ich würde das mit dem PW eh lassen. Leg das Skript irgendwo ab, wo nur User darauf Zugriff haben, die das sowieso dürfen.
Bin ich auch der Meinung, denn auch so steht das Passwort schon unverschlüsselt im RAM. Oder wenn Passwörter warum auch immer dann diese schon im Windows-Tresor ablegen (cmdkey) dann reicht der Windows Logon.
Member: rubberman
rubberman Aug 21, 2020 updated at 15:03:48 (UTC)
Goto Top
Zitat von @erikro:
AFAIK in Batches gar nicht. face-wink
Doch. Aber man muss schon masochistisch veranlagt sein oder ausreichend Spieltrieb haben ...
@echo off &setlocal

<nul set /p "=Enter your password: "  
call :HInput pw
echo Input length is %errorlevel%
setlocal EnableDelayedExpansion
echo Your password is !pw!
pause
goto :eof


:HInput [ByRef_VarName]
:: inspired by Carlos
if "%__HI__%" neq "__HI__" (  
  setlocal DisableDelayedExpansion EnableExtensions
  set "CR=" &set "S=" &set "N=0" &set "__HI__=__HI__"  
  for /f "skip=1" %%i in ('echo(^|replace ? . /u /w') do if not defined CR set "CR=%%i"  
  for /f %%i in ('"prompt $H &for %%b in (1) do rem"') do set "BS=%%i"  
)
set "C="  
for /f skip^=1^ delims^=^ eol^= %%i in ('replace ? . /u /w') do if not defined C set "C=%%i"  
setlocal EnableDelayedExpansion EnableExtensions
if "!CR!"=="!C!" (  
  echo(
  if "%~1"=="" (  
    echo(!S!
    endlocal &endlocal &exit /b %N%
  ) else (
    if defined S (
      for /f delims^=^ eol^= %%i in ("!S!") do endlocal &endlocal &set "%~1=%%i" &exit /b %N%  
    ) else endlocal &endlocal &set "%~1=" &exit /b 0  
  )
)
if "!BS!"=="!C!" (  
  set "C="  
  if defined S set /a "N -= 1" &set "S=!S:~,-1!" &<nul set /p "=%BS% %BS%"  
) else set /a "N += 1" &<nul set /p "=*"  
if not defined S (
  endlocal &set "N=%N%" &set "S=%C%"  
) else for /f delims^=^ eol^= %%i in ("!S!") do endlocal &set "N=%N%" &set "S=%%i%C%"  
goto HInput
Source: https://www.dostips.com/forum/viewtopic.php?f=3&t=6382

Zitat von @erikro:
Ich würde das mit dem PW eh lassen.
Amen.

Steffen