it-swarm.com.ru

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

Мне нужно проверить, установлена ​​ли переменная или нет. Я пробовал несколько методов, но они, похоже, не работают, когда %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
171
blak3r

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

IF [%1] == [] GOTO MyLabel

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

235
Dan Story

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

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

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

118
jamesdlin

Одно из лучших полу решений - скопировать %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% пуленепробиваемым, вы можете прочитать Как получить даже самые странные параметры командной строки?

31
jeb

От IF/?:

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

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

......

ОПРЕДЕЛЕННЫЕ условные работы просто как EXISTS за исключением того, что требуется имя переменной среды и возвращает true, если переменная окружения - определены.

15
Andy Morris

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

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

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

Пустая строка представляет собой пару 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" " "< "">"  (")(") "" :: ""-"  " "( )"">\>" ""
3
user6801759

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

Первоначально вопрос ОП гласил «переменная», а не «параметр», что очень сбивало с толку, тем более что это была ссылка номер один в Google для поиска способов проверки на наличие пустых переменных. Начиная с моего первоначального ответа, Стефан отредактировал исходный вопрос, чтобы использовать правильную терминологию, но вместо того, чтобы удалить свой ответ, я решил оставить его, чтобы прояснить любую путаницу, особенно в том случае, если Google все еще отправляет сюда людей для переменных:

% 1 IS НЕ ПЕРЕМЕННЫЙ! ЭТО IS ПАРАМЕТР КОМАНДНОЙ ЛИНИИ.

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

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

Чтобы проверить пустую переменную, вы используете синтаксис «если не определен» (команды явно для переменных не требуют никаких знаков процента), например:

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

3
user3343110

Сценарий 1:

Ввод («Удалить цитаты. 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 не был пустым, пустым или пустым):


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

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

Welcome!

Press any key to continue . . .

Примечание. Если вы установите переменную в операторе IF ( ) ELSE ( ), она не будет доступна для DEFINED до тех пор, пока она не выйдет из оператора «IF» (если только не включено «Delayed Variable Expansion»; после включения используйте восклицательный знак «!» Вместо символ процента "%"}.

Например:

Сценарий 2:

Ввод («Удалить цитаты. 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 Files> "Удалить Quotes.cmd" "Это" a "Тест"

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

Выполнить («Удалить Quotes.cmd») без каких-либо параметров в сценарии 2:

Результат:

Welcome!

Press any key to continue . . .
2
Mr. Rick

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

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

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

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

Если% 1 пуст, IF сравнивает "." к "." который оценит как истину.

2
aphoria

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

@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

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

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
kayleeFrye_onDeck

Подводя итог:

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

Этот код выведет «Пустую строку», если% 1 либо «», либо «или пусто. Добавил его к принятому ответу, который в настоящее время неверен.

2
GrayFace

С помощью ! вместо "для проверки пустой строки

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

У меня было много вопросов с большим количеством ответов в сети. Большинство работает для большинства вещей, но всегда есть угловой случай, который ломает каждый.
Возможно, это не сработает, если у него есть кавычки, может быть, оно сломается, если у него нет кавычек, синтаксическая ошибка, если у переменной есть пробел, некоторые будут работать только с параметрами (в отличие от переменных среды), другие методы позволяют пустому набору цитат проходить как «определенные», а некоторые более хитрые не позволят вам связать 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

Echo'd 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)
0
Hashbrown

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

"C:/Users/Me"

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

C:
cd /Users/Me

И, 2, что означает «определенный» или «неопределенный»? GIGO. Я использую по умолчанию, чтобы ловить ошибки. Если ввод не перехватывается, он падает, чтобы помочь (или команда по умолчанию). Таким образом, без ввода не является ошибкой. Вы можете попробовать перейти на вход и поймать ошибку, если она есть. (Хорошо, использование загрузок 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
0
Xorange