it-swarm.com.de

Wie kann ich testen, ob ein Parameter in einer Batchdatei leer ist?

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
171
blak3r

Verwenden Sie eckige Klammern anstelle von Anführungszeichen:

IF [%1] == [] GOTO MyLabel

Klammern sind unsicher : Verwenden Sie nur eckige Klammern.

235
Dan Story

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.

118
jamesdlin

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?

31
jeb

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.

15
Andy Morris

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
)
5
zackz

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" " "< "">"  (")(") "" :: ""-"  " "( )"">\>" ""
3
user6801759

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.)

3
user3343110

Skript 1:

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:

Skript 2:

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 . . .
2
Mr. Rick

Sie können verwenden 

if defined (variable) echo That's defined!
if not defined (variable) echo Nope. Undefined.
2
noname

Ich verwende das normalerweise:

IF "%1."=="." GOTO MyLabel

Wenn% 1 leer ist, vergleicht die IF "." zu "." das wird wahr auswerten.

2
aphoria

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
)
2
Kate

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
2

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.

2
GrayFace

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
0
Lin W

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:

  • Möchten Sie nur if überprüfen? Call :ifSet %var% && Echo set
  • Nur wenn nicht (nur die anderen)? Call :ifSet %var% || Echo set
  • Überprüfen eines übergebenen Arguments; funktioniert gut. Call :ifSet %1 && Echo set
  • Wollten Sie Ihren Scripts/Dupe-Code nicht verstopfen, also setzen Sie ihn in seinen eigenen ifSet.bat? Kein Problem: ((Call ifSet.bat %var%) && Echo set) || (Echo not set)
0
Hashbrown

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
0
Xorange