Ich muss testen, ob eine Variable gesetzt ist oder nicht. Ich habe verschiedene Techniken ausprobiert, aber sie scheinen zu versagen, wenn %1
von Anführungszeichen umgeben ist, beispielsweise wenn %1
"c:\some path with spaces"
ist.
IF NOT %1 GOTO MyLabel // This is invalid syntax
IF "%1" == "" GOTO MyLabel // Works unless %1 has double quotes which fatally kills bat execution
IF %1 == GOTO MyLabel // Gives an unexpected GOTO error.
Gemäß this site sind dies die unterstützten IF
-Syntaxtypen. Also sehe ich keinen Weg dafür.
IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command
Verwenden Sie eckige Klammern anstelle von Anführungszeichen:
IF [%1] == [] GOTO MyLabel
Klammern sind unsicher : Verwenden Sie nur eckige Klammern.
Sie können verwenden:
IF "%~1" == "" GOTO MyLabel
den äußeren Satz von Anführungszeichen entfernen. Im Allgemeinen ist diese Methode zuverlässiger als die Verwendung eckiger Klammern, da sie auch dann funktioniert, wenn die Variable Leerzeichen enthält.
Eine der besten Semi-Lösungen besteht darin, %1
in eine Variable zu kopieren und dann als delayedExp eine verzögerte Erweiterung zu verwenden. ist immer sicher vor jeglichem Inhalt.
set "param1=%~1"
setlocal EnableDelayedExpansion
if "!param1!"=="" ( echo it is empty )
rem ... or use the DEFINED keyword now
if defined param1 echo There is something
Dies hat den Vorteil, dass der Umgang mit param1 absolut sicher ist.
Die Einstellung von param1 wird in vielen Fällen funktionieren, z
test.bat hello"this is"a"test
test.bat you^&me
Aber es wird mit seltsamen Inhalten scheitern
test.bat "&"^&
Wenn Sie zu 99% kugelsicher sein wollen, können Sie lesen Wie erhalten Sie auch die seltsamsten Befehlszeilenparameter?
Von IF/?:
Wenn Befehlserweiterungen aktiviert sind, WENN ändert sich wie folgt:
IF [/I] string1 compare-op string2 command IF CMDEXTVERSION number command IF DEFINED variable command
......
Die DEFINED-Bedingung funktioniert nur wie EXISTS, es sei denn, es braucht ein Umgebungsvariablenname und gibt zurück true, wenn die Umgebungsvariable .__ ist. definiert.
Verwenden Sie "IF DEFINED variable command", um die Variable in der Stapeldatei zu testen.
Wenn Sie Batch-Parameter testen möchten, versuchen Sie es mit den folgenden Codes, um schwierige Eingaben zu vermeiden (z. B. "1 2" oder ab ^> cd).
set tmp="%1"
if "%tmp:"=.%"==".." (
echo empty
) else (
echo not empty
)
Leere Zeichenfolge ist ein Paar von double-quotes
/""
, wir können nur die Länge testen:
set ARG=%1
if not defined ARG goto nomore
set CHAR=%ARG:~2,1%
if defined CHAR goto goon
dann teste es 2 Zeichen gegen double-quotes
:
if ^%ARG:~1,1% == ^" if ^%ARG:~0,1% == ^" goto blank
::else
goto goon
Hier ist ein Batch-Skript, mit dem Sie spielen können. Ich denke, es fängt den leeren String richtig ein.
Dies ist nur ein Beispiel. Sie müssen lediglich zwei (oder drei?) Schritte entsprechend Ihrem Skript anpassen.
@echo off
if not "%OS%"=="Windows_NT" goto EOF
:: I guess we need enableExtensions, CMIIW
setLocal enableExtensions
set i=0
set script=%0
:LOOP
set /a i=%i%+1
set A1=%1
if not defined A1 goto nomore
:: Assumption:
:: Empty string is (exactly) a pair of double-quotes ("")
:: Step out if str length is more than 2
set C3=%A1:~2,1%
if defined C3 goto goon
:: Check the first and second char for double-quotes
:: Any characters will do fine since we test it *literally*
if ^%A1:~1,1% == ^" if ^%A1:~0,1% == ^" goto blank
goto goon
:goon
echo.args[%i%]: [%1]
shift
goto LOOP
:blank
echo.args[%i%]: [%1] is empty string
shift
goto LOOP
:nomore
echo.
echo.command line:
echo.%script% %*
:EOF
Dieses Folter-Test-Ergebnis:
.test.bat :: "" ">"""bl" " "< "">" (")(") "" :: ""-" " "( )"">\>" ""
args[1]: [::]
args[2]: [""] is empty string
args[3]: [">"""bl" "]
args[4]: ["< "">"]
args[5]: [(")(")]
args[6]: [""] is empty string
args[7]: [::]
args[8]: [""-" "]
args[9]: ["( )"">\>"]
args[10]: [""] is empty string
command line:
.test.bat :: "" ">"""bl" " "< "">" (")(") "" :: ""-" " "( )"">\>" ""
Leider habe ich nicht genug Ruf, um die aktuellen Antworten zu kommentieren oder abzustimmen, zu denen ich meine eigenen schreiben musste.
Ursprünglich lautete die Frage des OP "Variable" und nicht "Parameter", was sehr verwirrend wurde, zumal dies bei google die Nummer eins war, um nach leeren Variablen zu suchen. Seit meiner ursprünglichen Antwort hat Stephan die ursprüngliche Frage so bearbeitet, dass er die korrekte Terminologie verwendet, aber anstatt meine Antwort zu löschen, beschloss ich, sie zu lassen, um Verwirrungen zu beseitigen, vor allem, wenn Google immer noch Leute nach Variablen schickt:
% 1 IS KEINE VARABLE! IT IS EIN BEFEHLSZEILENPARAMETER.
Sehr wichtige Unterscheidung. Ein einzelnes Prozentzeichen mit einer Zahl hinter diesem bezieht sich auf einen Befehlszeilenparameter und keine Variable.
Variablen werden mit dem Befehl set gesetzt und mit 2 Prozentzeichen abgerufen - eines vor und eines nach dem anderen. Zum Beispiel% myvar%
Um auf eine leere Variable zu testen, verwenden Sie die Syntax "Wenn nicht definiert" (Befehle, die explizit für Variablen verwendet werden, erfordern keine Prozentzeichen). Beispiel:
set myvar1=foo
if not defined myvar1 echo You won't see this because %myvar1% is defined.
if not defined myvar2 echo You will see this because %myvar2% isn't defined.
(Wenn Sie Befehlszeilenparameter testen möchten, empfehle ich die Antwort von jamesdlin.)
Eingabe ("Remove Quotes.cmd" "Dies ist ein Test")
@ECHO OFF
REM Set "string" variable to "first" command line parameter
SET STRING=%1
REM Remove Quotes [Only Remove Quotes if NOT Null]
IF DEFINED STRING SET STRING=%STRING:"=%
REM IF %1 [or String] is NULL GOTO MyLabel
IF NOT DEFINED STRING GOTO MyLabel
REM OR IF "." equals "." GOTO MyLabel
IF "%STRING%." == "." GOTO MyLabel
REM GOTO End of File
GOTO :EOF
:MyLabel
ECHO Welcome!
PAUSE
Ausgabe (es gibt keine,% 1 war NICHT leer, leer oder NULL):
Führen Sie ("Remove Quotes.cmd") ohne Parameter mit dem obigen Skript aus. 1
Ausgabe (% 1 ist leer, leer oder NULL):
Welcome!
Press any key to continue . . .
Anmerkung: Wenn Sie eine Variable innerhalb einer IF ( ) ELSE ( )
-Anweisung setzen, ist sie für DEFINED erst verfügbar, nachdem sie die "IF" -Anweisung beendet hat (sofern "Erweiterung verzögerter Variablen" nicht aktiviert ist; verwenden Sie nach dem Aktivieren ein Ausrufezeichen "!" Anstelle von das Prozentzeichen "%"}.
Zum Beispiel:
Eingabe ("Remove Quotes.cmd" "Dies ist ein Test")
@ECHO OFF
SETLOCAL EnableDelayedExpansion
SET STRING=%0
IF 1==1 (
SET STRING=%1
ECHO String in IF Statement='%STRING%'
ECHO String in IF Statement [delayed expansion]='!STRING!'
)
ECHO String out of IF Statement='%STRING%'
REM Remove Quotes [Only Remove Quotes if NOT Null]
IF DEFINED STRING SET STRING=%STRING:"=%
ECHO String without Quotes=%STRING%
REM IF %1 is NULL GOTO MyLabel
IF NOT DEFINED STRING GOTO MyLabel
REM GOTO End of File
GOTO :EOF
:MyLabel
ECHO Welcome!
ENDLOCAL
PAUSE
Ausgabe:
C:\Users\Test>"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd" "This is a Test"
String in IF Statement='"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"'
String in IF Statement [delayed expansion]='"This is a Test"'
String out of IF Statement='"This is a Test"'
String without Quotes=This is a Test
C:\Users\Test>
Hinweis: Es werden auch Anführungszeichen aus dem String entfernt.
Für Beispiel (mit Skript 1 oder 2): C:\Users\Test\Documents\Batch-Dateien> "Quotes.cmd entfernen" "Dies ist" ein "Test"
Ausgabe (Skript 2):
String in IF Statement='"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"'
String in IF Statement [delayed expansion]='"This is "a" Test"'
String out of IF Statement='"This is "a" Test"'
String without Quotes=This is a Test
Führen Sie ("Remove Quotes.cmd") ohne Parameter in Skript 2 aus:
Ausgabe:
Welcome!
Press any key to continue . . .
Sie können verwenden
if defined (variable) echo That's defined!
if not defined (variable) echo Nope. Undefined.
Ich verwende das normalerweise:
IF "%1."=="." GOTO MyLabel
Wenn% 1 leer ist, vergleicht die IF "." zu "." das wird wahr auswerten.
Ich teste mit dem folgenden Code und es ist in Ordnung.
@echo off
set varEmpty=
if not "%varEmpty%"=="" (
echo varEmpty is not empty
) else (
echo varEmpty is empty
)
set varNotEmpty=hasValue
if not "%varNotEmpty%"=="" (
echo varNotEmpty is not empty
) else (
echo varNotEmpty is empty
)
Ich habe dieses kleine Batch-Skript basierend auf den Antworten erstellt, da es viele gültige gibt. Fühlen Sie sich frei, dies hinzuzufügen, solange Sie dasselbe Format verwenden:
REM Parameter-testing
Setlocal EnableDelayedExpansion EnableExtensions
IF NOT "%~1"=="" (echo Percent Tilde 1 failed with quotes) ELSE (echo SUCCESS)
IF NOT [%~1]==[] (echo Percent Tilde 1 failed with brackets) ELSE (echo SUCCESS)
IF NOT "%1"=="" (echo Quotes one failed) ELSE (echo SUCCESS)
IF NOT [%1]==[] (echo Brackets one failed) ELSE (echo SUCCESS)
IF NOT "%1."=="." (echo Appended dot quotes one failed) ELSE (echo SUCCESS)
IF NOT [%1.]==[.] (echo Appended dot brackets one failed) ELSE (echo SUCCESS)
pause
Zusammenfassend:
set str=%~1
if not defined str ( echo Empty string )
Dieser Code gibt "Leere Zeichenfolge" aus, wenn% 1 entweder "" oder "oder leer ist. Er wurde der akzeptierten Antwort hinzugefügt, die derzeit falsch ist.
Mit! anstelle von "zur Überprüfung leerer Zeichenfolgen
@echo off
SET a=
SET b=Hello
IF !%a%! == !! echo String a is empty
IF !%b%! == !! echo String b is empty
Ich hatte viele Probleme mit vielen Antworten im Netz. Die meisten arbeiten für die meisten Dinge, aber es gibt immer einen Eckfall, bei dem jede davon gebrochen wird.
Vielleicht funktioniert es nicht, wenn es Anführungszeichen hat, vielleicht bricht es, wenn es keine Anführungszeichen gibt, Syntaxfehler, wenn die Variable ein Leerzeichen enthält, einige funktionieren nur mit Parametern (im Gegensatz zu Umgebungsvariablen), anderen Techniken Lassen Sie zu, dass ein leerer Satz von Anführungszeichen als 'definiert' übergeben wird. Bei einigen kniffligen Anhängen können Sie anschließend keine else
verketten.
Hier ist eine Lösung, mit der ich zufrieden bin. Bitte lassen Sie mich wissen, wenn Sie einen Eckfall finden, für den es nicht funktioniert.
:ifSet
if "%~1"=="" (Exit /B 1) else (Exit /B 0)
Wenn Sie dieses Unterprogramm entweder in einem Skript oder in seinem eigenen .bat
haben, sollte es funktionieren.
.__ Wenn Sie also (in Pseudo) schreiben wollten:
if (var)
then something
else somethingElse
Du kannst schreiben:
(Call :ifSet %var% && (
Echo something
)) || (
Echo something else
)
Es hat für alle meine Tests funktioniert:
(Call :ifSet && ECHO y) || ECHO n
(Call :ifSet a && ECHO y) || ECHO n
(Call :ifSet "" && ECHO y) || ECHO n
(Call :ifSet "a" && ECHO y) || ECHO n
(Call :ifSet "a a" && ECHO y) || ECHO n
Echo würde n
, y
, n
, y
, y
Mehr Beispiele:
if
überprüfen? Call :ifSet %var% && Echo set
Call :ifSet %var% || Echo set
Call :ifSet %1 && Echo set
ifSet.bat
? Kein Problem: ((Call ifSet.bat %var%) && Echo set) || (Echo not set)
Ich bin in weniger als einem Monat eingezogen (obwohl es vor 8 Jahren gefragt wurde) ... Ich hoffe, dass er/sie sich inzwischen über Batch-Dateien hinaus bewegt hat. ; -) Ich habe das immer gemacht. Ich bin mir jedoch nicht sicher, was das Endziel ist. Wenn er/sie faul ist wie ich, funktioniert meine go.bat für solche Sachen. (Siehe unten) Der Befehl im OP kann jedoch ungültig sein, wenn Sie die Eingabe direkt als Befehl verwenden. d.h.
"C:/Users/Me"
ist ein ungültiger Befehl (oder früher, wenn Sie sich auf einem anderen Laufwerk befanden). Sie müssen es in zwei Teile zerlegen.
C:
cd /Users/Me
Und 2, was bedeutet "definiert" oder "undefiniert"? GIGO. Ich verwende die Standardeinstellung, um Fehler abzufangen. Wenn die Eingabe nicht abgefangen wird, wird sie gelöscht (oder ein Standardbefehl). Keine Eingabe ist also kein Fehler. Sie können versuchen, zur Eingabe zu wechseln und den Fehler abzufangen, falls vorhanden. (Ok, mit "go" -Downloads (nur eine Parne) wird von DOS abgefangen. (Harsh!))
cd "%1"
if %errorlevel% neq 0 goto :error
Und 3, Anführungszeichen werden nur um den Pfad benötigt, nicht um den Befehl. d.h.
"cd C:\Users"
war schlecht (oder früher gewohnt), es sei denn, Sie waren auf einer anderen Festplatte.
cd "\Users"
ist funktionell.
cd "\Users\Dr Whos infinite storage space"
funktioniert, wenn Sie Leerzeichen in Ihrem Pfad haben.
@REM go.bat
@REM The @ sigh prevents echo on the current command
@REM The echo on/off turns on/off the echo command. Turn on for debugging
@REM You can't see this.
@echo off
if "help" == "%1" goto :help
if "c" == "%1" C:
if "c" == "%1" goto :done
if "d" == "%1" D:
if "d" == "%1" goto :done
if "home"=="%1" %homedrive%
if "home"=="%1" cd %homepath%
if "home"=="%1" if %errorlevel% neq 0 goto :error
if "home"=="%1" goto :done
if "docs" == "%1" goto :docs
@REM goto :help
echo Default command
cd %1
if %errorlevel% neq 0 goto :error
goto :done
:help
echo "Type go and a code for a location/directory
echo For example
echo go D
echo will change disks (D:)
echo go home
echo will change directories to the users home directory (%homepath%)
echo go pictures
echo will change directories to %homepath%\pictures
echo Notes
echo @ sigh prevents echo on the current command
echo The echo on/off turns on/off the echo command. Turn on for debugging
echo Paths (only) with folder names with spaces need to be inclosed in quotes (not the ommand)
goto :done
:docs
echo executing "%homedrive%%homepath%\Documents"
%homedrive%
cd "%homepath%\Documents"\test error\
if %errorlevel% neq 0 goto :error
goto :done
:error
echo Error: Input (%1 %2 %3 %4 %5 %6 %7 %8 %9) or command is invalid
echo go help for help
goto :done
:done