Как правильно проверить, пуст ли параметр в пакетном файле?

мне нужно проверить, установлена ли переменная или нет. Я пробовал несколько методов, но они, похоже, терпят неудачу, когда %1 окружен кавычками, такими как случай, когда %1 и "c:some path with spaces".

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.

по данным этот сайт, это поддерживает IF типы синтаксиса. Так что я не вижу способа сделать это.

IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command

16 ответов


вместо кавычек используйте квадратные скобки:

IF [%1] == [] GOTO MyLabel

скобки неуверенность: использовать только квадратные скобки.


вы можете использовать:

IF "%~1" == "" GOTO MyLabel

чтобы удалить внешний набор кавычек. В общем, это более надежный метод, чем использование квадратных скобок, потому что он будет работать, даже если переменная имеет пробелы.


одним из лучших решений semi является копирование %1 в переменную, а затем использовать отложенное расширение, как delayedExp. всегда безопасен против любого содержания.

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

преимущество этого заключается в том, что работа с param1 абсолютно безопасна.

и настройка param1 будет работать во многих случаях, как

test.bat hello"this is"a"test
test.bat you^&me

но он потерпит неудачу со странным содержимым, таким как

test.bat "&"^&

если вы хотите быть 99% пуленепробиваемым, вы можете прочитать как получите даже самые странные параметры командной строки?


от IF/?:

Если расширения команд включены, если изменения следующим образом:

IF [/I] string1 compare-op string2 command
IF CMDEXTVERSION number command
IF DEFINED variable command

......

определенное условное работает только подобное существует, но для этого требуется имя переменной среды и возвращает true, если переменная окружения определенный.


используйте "IF DEFINED variable command" для проверки переменной в пакетном файле.

но если вы хотите проверить параметры пакета, попробуйте ниже коды, чтобы избежать сложного ввода (например, "1 2" или ab^>cd)

set tmp="%1"
if "%tmp:"=.%"==".." (
    echo empty
) else (
    echo not empty
)

пустая строка-это пара double-quotes/"", мы можем просто проверить длина:

set ARG=%1
if not defined ARG goto nomore

set CHAR=%ARG:~2,1%
if defined CHAR goto goon

затем проверьте, что это 2 символа против double-quotes:

if ^%ARG:~1,1% == ^" if ^%ARG:~0,1% == ^" goto blank
::else
goto goon

вот пакетный скрипт, с которым вы можете играть. Я думаю, он правильно ловит пустую струну.

это просто пример, вам просто нужно настроить 2 (или 3?) шаги выше в соответствии с вашим сценарием.

@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

этот результат теста пытки:

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

к сожалению, у меня недостаточно репутации, чтобы комментировать или голосовать за текущие ответы, которые мне пришлось написать.

первоначально вопрос OP сказал "переменная", а не" параметр", что стало очень запутанным, тем более, что это была ссылка номер один в google для поиска того, как тестировать пустые переменные. С момента моего первоначального ответа Стефан отредактировал исходный вопрос, чтобы использовать правильную терминологию, но вместо того, чтобы удалить мой ответ, я решил оставить его помогите прояснить любую путаницу, особенно если google все еще отправляет людей сюда для переменных:

%1 НЕ ЯВЛЯЕТСЯ ИЗМЕНЯЕМЫМ! ЭТО ПАРАМЕТР КОМАНДНОЙ СТРОКИ.

очень важное различие. Один знак процента с номером после того, как он ссылается на параметр командной строки, а не на переменную.

переменные устанавливаются с помощью команды set и вызываются с использованием 2 - процентных знаков-один до и один после. Например %аргумент myVar%

чтобы проверить пустую переменную, вы используете синтаксис "if not defined" (команды явно для переменных не требуют знаков процента), например:

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.

(Если вы хотите проверить параметры командной строки, я рекомендую обратиться к ответу jamesdlin.)


Я обычно использую этот:

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

если %1 пуст, то IF будет сравнивать "." к." - которая будет оценена как истинная.


Сценарий 1:

Input ("Удалить Кавычки.cmd ""это тест")

@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

вывод (Нет, %1 не был пустым, пустым или нулевым):


"Выполнить" ("Удалить Кавычки.cmd") без каких-либо параметров с указанным выше скриптом 1

вывод (%1 пустой, пустой или NULL):

Welcome!

Press any key to continue . . .

Примечание: Если вы установите переменную внутри IF ( ) ELSE ( ) оператор, он не будет доступен для определения до тех пор, пока он не выйдет из оператора " IF (если не включено "отложенное расширение переменной"; после включения используйте восклицательный знак"!"вместо символа процента"%"}.

например:

Сценарий 2:

Input ("Удалить Кавычки.cmd ""это тест")

@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

выход:

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>  

Примечание: он также удалит кавычки из строки.

например (используя скрипт 1 или 2): C:\Users\Test\Documents\Batch Файлы> " Удалить Кавычки.УМК" "это "а" тест"

Вывод (Сценарий 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  

Execute ("Удалить Кавычки.cmd") без каких-либо параметров в скрипте 2:

выход:

Welcome!

Press any key to continue . . .

Я создал небольшой скрипт, на основе ответов здесь, так как есть много убедительных доказательств. Не стесняйтесь добавлять к этому, пока вы следуете тому же формату:

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

в итоге:

set str=%~1
if not defined str ( echo Empty string )

этот код выведет "пустую строку", если %1 является "Или" Или " или пустым. Добавил его к принятому ответу, который в настоящее время неверен.


можно использовать

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

у меня было много вопросов, много ответов в сети. Большинство работает для большинства вещей, но всегда есть случай, который ломает каждого.
Возможно, он не работает, если у него есть кавычки, возможно, он ломается, если у него нет кавычек, синтаксическая ошибка, если у var есть пробел, некоторые будут работать только с параметрами (в отличие от переменных среды), другие методы позволяют пустому набору кавычек проходить как "определенные", а некоторые более сложные не позволят вам цеплять else потом.

вот решение, которым я доволен, пожалуйста, дайте мне знать, если вы найдете угловой случай, он не будет работать.

:ifSet
if "%~1"=="" (Exit /B 1) else (Exit /B 0)

имея эту подпрограмму либо в вашем скрипте, либо в своем собственном .bat, должно работать.
Поэтому, если вы хотите написать (в псевдо):

if (var)
then something
else somethingElse

вы можете написать:

(Call :ifSet %var% && (
    Echo something
)) || (
    Echo something else
)

это сработало для всех моих тестов:

(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

Эхо бы n, y, n, y, y


примеры:

  • хочу просто проверить if? Call :ifSet %var% && Echo set
  • просто если нет (только другой)? Call :ifSet %var% || Echo set
  • проверка переданного аргумента; работает нормально. Call :ifSet %1 && Echo set
  • не хотел засорять ваши скрипты / обманывать код, поэтому вы положили его в свой собственный ifSet.bat? Нет проблем: ((Call ifSet.bat %var%) && Echo set) || (Echo not set)

использование ! Вместо " для проверки пустой строки

@echo off
SET a=
SET b=Hello
IF !%a%! == !! echo String a is empty
IF !%b%! == !! echo String b is empty

Я тестирую с кодом ниже, и это нормально.

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

Я вошел в чуть меньше месяца (хотя это было предложено 8 лет назад)... Надеюсь, s / he уже вышел за рамки пакетных файлов. ;-) Я всегда так делал. Хотя я не уверен, какова конечная цель. Если он ленивый, как я, мой ход.Бэт работает для таких вещей. (Смотреть ниже) Но, 1, команда в OP может быть недопустимой, если вы непосредственно используете ввод в качестве команды. т. е.

"C:/Users/Me"

- это недопустимая команда (или раньше, если вы были на другом диске). Нужно разбить его на две части.

C:
cd /Users/Me

и, 2, что означает "определенный" или "неопределенный"? ДЖИГО. Я использую значение по умолчанию для обнаружения ошибок. Если вход не пойман, он падает, чтобы помочь (или команда по умолчанию). Таким образом, никакой ввод не является ошибкой. Вы можете попробовать cd на вход и поймать ошибку, если она есть. (Хорошо, используя go " загрузки (только один парен) пойман DOS. (Сурово!))

cd "%1"
if %errorlevel% neq 0 goto :error

и, 3, кавычки нужны только вокруг пути, а не команды. т. е.,

"cd C:\Users" 

было плохо (или использовалось в старые времена), если вы не были на другом диске.

cd "\Users" 

работает.

cd "\Users\Dr Whos infinite storage space"

работает, если у вас есть пробелы в пути.

@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