117 Stimmen

Wie kann ich überprüfen, ob ein Argument definiert ist, wenn ich eine Stapeldatei starte/aufrufe?

Ich versuche, die folgende Validierungslogik in einer Stapeldatei zu verwenden, aber der "Verwendung"-Block wird nie ausgeführt, auch wenn kein Parameter an die Stapeldatei übergeben wird.

if ("%1"=="") goto usage

@echo Dies sollte nicht ausgeführt werden

@echo Erledigt.
goto :eof

:usage
@echo Verwendung: %0 
exit 1

Was mache ich falsch?

0 Stimmen

1 Stimmen

@double-beep - Die Frage hier (von daniel-fortunov) wurde zuerst gestellt, etwa ein Jahr bevor die Frage, auf die Sie sich beziehen, veröffentlicht wurde. Welches ist das (mögliche) Duplikat?

1 Stimmen

@KevinFegan, weil die andere Frage mehr Aufrufe und mehr Antworten hat.

185voto

Iain Punkte 9943

Die Überprüfung, ob ein Befehlszeilenargument festgelegt wurde, kann [%1]==[] sein, aber wie Dave Costa darauf hingewiesen hat, funktioniert auch "%1"=="".

Ich habe auch einen Syntaxfehler bei der Verwendung von echo behoben, um die größer-als und kleiner-als Zeichen zu escapen. Außerdem benötigt das exit ein /B Argument, ansonsten wird CMD.exe beendet.

@echo off

if [%1]==[] goto usage
@echo Dies sollte nicht ausgeführt werden
@echo Fertig.
goto :eof
:usage
@echo Verwendung: %0 ^
exit /B 1

26 Stimmen

[%1]==[] ist besser als "%1"== "", weil es den Fall korrekt behandelt, in dem %1 selbst doppelte Anführungszeichen enthält. "%1"=="" wird mit einer "unerwartet zu diesem Zeitpunkt" Nachricht einen Fehler anzeigen.

2 Stimmen

Beachten Sie, dass, wenn Sie keine Befehlszeilenargumente verwenden, sondern set-Variablen (ich kenne die korrekte Batch-Terminologie nicht), möchten Sie möglicherweise "%myvar%"=="" verwenden, da wenn myvar Leerzeichen enthält und nicht in Anführungszeichen steht, erhalten Sie die Meldung "unerwartet zu dieser Zeit".

1 Stimmen

@Pat SET-Variablen könnten mit dem IF NOT DEFINED VarName-Block überprüft werden. Außerdem ein zusätzliches Lob an tukushan, dass er keine Anführungszeichen im Vergleich verwendet hat. Einfach nicht machen. Niemals.

28voto

Ein fortgeschrittenes Beispiel:

unendliche Argumente.

existieren im Dateisystem (entweder als Datei oder Verzeichnis?) oder als generischer String.

spezifizieren, ob es eine Datei ist

spezifizieren, ob es ein Verzeichnis ist

keine Erweiterungen, funktioniert in Legacy-Skripten!

minimaler Code

@echo off

:schleife
      ::-------------------------- hat Argument ?
      if \["%~1"\]==\[""\] (
        echo fertig.
        goto ende
      )
      ::-------------------------- Argument existiert ?
      if not exist %~s1 (
        echo existiert nicht
      ) else (
        echo existiert
        if exist %~s1\\NUL (
          echo ist ein Verzeichnis
        ) else (
          echo ist eine Datei
        )
      )
      ::--------------------------
      shift
      goto schleife

:ende

pause

andere Sachen..

in %~1 - das ~ entfernt jegliche umschließenden " oder '.

in %~s1 - das s macht den Pfad zu DOS 8.3-Namen, was ein netter Trick ist, um Leerzeichen im Dateinamen zu vermeiden während des Überprüfens von Sachen (und auf diese Weise ist kein zusätzliches Einwickeln der Ressource mit mehreren "s erforderlich).

das ["%~1"]==[""] "kann nicht sicher sein", ob das Argument eine Datei/Verzeichnis ist oder nur ein generischer String, daher verwendet der Ausdruck Klammern und das originale unveränderte %1 (nur ohne das " Einwickeln, falls vorhanden..)

wenn es keine Argumente gab oder wenn wir shift verwendet haben und der Argument-Liste-Zeiger das letzte überschritten hat, wird der Ausdruck zu [""]==[""] ausgewertet.

das ist so spezifisch, wie man sein kann, ohne weitere Tricks zu verwenden (es würde sogar in Batch-Skripts von windows-95 funktionieren...)

Ausführungsbeispiele

speichern Sie es als identifier.cmd

es kann eine unendliche Anzahl von Argumenten identifizieren (normalerweise sind Sie auf %1-%9 beschränkt), denken Sie nur daran, die Argumente mit umgekehrten Anführungszeichen zu umschließen, oder verwenden Sie 8.3-Namen, oder ziehen Sie sie darüber (es macht automatisch eines der oben genannten).


dadurch können Sie die folgenden Befehle ausführen:

identifier.cmd c:\windows und erhalten

existiert
ist ein Verzeichnis
fertig.

identifier.cmd "c:\Program Files (x86)\Microsoft Office\OFFICE11\WINWORD.EXE" und erhalten

existiert
ist eine Datei
fertig.

und mehrere Argumente (natürlich ist das die ganze Sache..)

identifier.cmd c:\windows\system32 c:\hiberfil.sys "c:\pagefile.sys" hello-world

und erhalten

existiert
ist ein Verzeichnis
existiert
ist eine Datei
existiert
ist eine Datei
existiert nicht
fertig.

natürlich kann es viel komplexer sein, aber schöne Beispiele sollten immer einfach und minimal sein. :)

Hoffentlich hilft es jemandem :)

veröffentlicht hier:<a href="http://icompile.eladkarako.com/cmd-unlimited-arguments-identifying-directory-file-or-none/" rel="noreferrer">CMD Ninja - Unbegrenzte Argumentverarbeitung, Identifizierung, ob im Dateisystem vorhanden, Identifizierung als Datei oder Verzeichnis</a>

und hier ist ein funktionierendes Beispiel, das beliebig viele APK-Dateien (Android-Apps) akzeptiert und sie über die Debug-Konsole (ADB.exe) auf Ihrem Gerät installiert: <a href="http://icompile.eladkarako.com/mass-apk-installer-wo-adb-install-multi/" rel="noreferrer">Machen Sie den vorherigen Beitrag zu einem Massen-APK-Installer, der die Syntax ADB Install-Multi nicht verwendet</a>

0 Stimmen

Der Link zum CMD Ninja hat bei mir nicht funktioniert, aber eine archivierte Version schon. Übrigens, sehr schöne Zusammenfassung!

0 Stimmen

Sie können einfach `:eof` verwenden und dann ist kein Label erforderlich. Es ist implizit. ss64.com/nt/goto.html

16voto

Dave Costa Punkte 45801

Die Klammern loswerden.

Beispiel-Batch-Datei:

echo "%1"

if ("%1"=="") echo match1

if "%1"=="" echo match2

Ausgabe beim Ausführen des obigen Skripts:

C:\>echo "" 
""

C:\>if ("" == "") echo match1 

C:\>if "" == "" echo match2 
match2

Ich glaube, dass die Klammern tatsächlich als Teil der Zeichenketten betrachtet werden und verglichen werden.

1 Stimmen

if "%1"=="" wird abstürzen, wenn das Argument Leerzeichen enthält. Zum Beispiel: run.bat "a b". @amr hat die beste Antwort, um if "%~1"=="" zu verwenden.

6voto

Amr Ali Punkte 2068
IF "%~1"=="" GOTO :Verwendung

~ de-quoted %1, falls %1 selbst in Anführungszeichen steht.

" " schützen vor speziellen Zeichen, die übergeben werden. Zum Beispiel beim Aufruf des Skripts mit &ping

1 Stimmen

Dies ist die beste Antwort. Die anderen Antworten funktionieren für einige Fälle, werden jedoch für speziellere Fälle wie run.bat "a b" fehlschlagen.

0 Stimmen

@wisbucky Das scheint die akzeptierte Antwort nicht durcheinander zu bringen. Was übersehe ich?

0 Stimmen

@ruffin, Beispiel: run.bat "" wird nicht von [%1]==[] erfasst.

4voto

masterxilo Punkte 2219

Dies entspricht den anderen Antworten, verwendet jedoch nur ein Label und setzt die Verwendung an erster Stelle, was es zusätzlich als eine Art Dokumentationskommentar des Skripts fungieren lässt, das in der Regel auch oben platziert wird:

@echo off
:: füge hier einen anderen Test für die Argumente hinzu...
if not [%1]==[] goto main
:: --------------------------
echo Diese Befehl tut etwas.
echo.
echo %0 param%%1 param%%2
echo       param%%1 die Datei, auf der gearbeitet werden soll
echo       param%%1 eine weitere Datei

:: --------------------------
exit /B 1

:main
:: --------------------------
tue etwas mit allen Argumenten (%%* == %*) hier...

Wenn Sie jedoch nicht cmd/batch verwenden müssen, verwenden Sie bash auf WSL oder PowerShell, sie haben eine vernünftigere Syntax und weniger versteckte Funktionen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X