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

<p>мне нужно проверить, установлена ли переменная или нет. я пробовал несколько методов, но они, похоже, не работают, когда <code>%1</code> заключен в кавычки, например, когда <code>%1</code> равен <code>"c:\some path with spaces"</code>.</p><pre><code>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. </code></pre><p>согласно <a href="http://www.computerhope.com/if.htm">этот сайт</a> , это поддерживаемые типы синтаксиса <code>if</code>. так что я не вижу способа сделать это.</p><pre><code>if [not] errorlevel number command if [not] string1==string2 command if [not] exist filename command </code></pre>

<p>используйте квадратные скобки вместо кавычек:</p><pre><code>if [%1] == [] goto mylabel </code></pre><p>скобки<strong> небезопасны </strong>: используйте только квадратные скобки.</p>

<p>ты можешь использовать:</p><pre><code>if "%~1" == "" goto mylabel </code></pre><p>раздеть внешний набор цитат. в целом, это более надежный метод, чем использование квадратных скобок, поскольку он будет работать, даже если в переменной есть пробелы.</p>

<p>одно из лучших полу решений - скопировать <code>%1</code> в переменную, а затем использовать отложенное расширение, как delayedexp. всегда безопасен от любого контента. </p><pre><code>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 </code></pre><p>преимущество этого в том, что работа с param1 абсолютно безопасна. </p><p>и настройка param1 будет работать во многих случаях, например,</p><pre><code>test.bat hello"this is"a"test test.bat you^&me </code></pre><p>но это не удастся со странным содержанием, как</p><pre><code>test.bat "&"^& </code></pre><p>если вы хотите быть на 99% пуленепробиваемым, вы можете прочитать <a href="https://stackoverflow.com/q/4200316/463115">как получить даже самые странные параметры командной строки?</a> </p>

<p>от if/?:</p><blockquote> <p>если расширения команд включены, если изменяется следующим образом:</p> <pre><code>if [/i] string1 compare-op string2 command if cmdextversion number command if defined variable command </code></pre> <p>......</p> <p>определенные условные работы просто как exists за исключением того, что требуется имя переменной среды и возвращает true, если переменная окружения - определены.</p> </blockquote>

<p>используйте «if defined variable command» для проверки переменной в командном файле.</p><p>но если вы хотите проверить параметры пакета, попробуйте следующие коды, чтобы избежать хитрого ввода (например, «1 2» или ab ^> cd)</p><pre><code>set tmp="%1" if "%tmp:"=.%"==".." ( echo empty ) else ( echo not empty ) </code></pre>

<p>пустая строка представляет собой пару <code>double-quotes</code>/<code>""</code>, мы можем просто проверить длину:</p><pre><code>set arg=%1 if not defined arg goto nomore set char=%arg:~2,1% if defined char goto goon </code></pre><p>затем проверьте 2 символа против <code>double-quotes</code>:</p><pre><code>if ^%arg:~1,1% == ^" if ^%arg:~0,1% == ^" goto blank ::else goto goon </code></pre><p>вот пакетный скрипт, с которым вы можете играть. я думаю, что это правильно ловит пустую строку.</p><p>это всего лишь пример, вам просто нужно настроить 2 (или 3?) шага выше в соответствии с вашим сценарием.</p><pre><code>@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 </code></pre><p>этот результат теста на пытки:</p><pre><code>.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" " "< "">" (")(") "" :: ""-" " "( )"">\>" "" </code></pre>

<p>к сожалению, у меня недостаточно репутации, чтобы комментировать или голосовать за текущие ответы, поэтому я должен был написать свой собственный.</p><p>первоначально вопрос оп гласил «переменная», а не «параметр», что очень сбивало с толку, тем более что это была ссылка номер один в google для поиска способов проверки на наличие пустых переменных. начиная с моего первоначального ответа, стефан отредактировал исходный вопрос, чтобы использовать правильную терминологию, но вместо того, чтобы удалить свой ответ, я решил оставить его, чтобы прояснить любую путаницу, особенно в том случае, если google все еще отправляет сюда людей для переменных:</p><p><strong>% 1 is не переменный! это is параметр командной линии. </strong></p><p>очень важное различие. один знак процента с числом после него относится к параметру командной строки, а не к переменной.</p><p><strong> переменные устанавливаются с помощью команды set и вызываются с использованием 2-процентных знаков - один до и один после. например% myvar% </strong></p><p>чтобы проверить пустую переменную, вы используете синтаксис «если не определен» (команды явно для переменных не требуют никаких знаков процента), например:</p><pre><code>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. </code></pre><p>(если вы хотите проверить параметры командной строки, тогда я рекомендую обратиться к ответу jamesdlin.)</p>

<h1>сценарий 1:</h1><p>ввод («удалить цитаты. cmd» «это тест»)</p><pre><code>@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 </code></pre><p>вывод (нет ни одного,% 1 не был пустым, пустым или пустым):</p><hr><p>выполнить ("удалить quotes.cmd") без каких-либо параметров с вышеупомянутым скриптом 1</p><p>вывод (% 1 пусто, пусто или null):</p><pre><code>welcome! press any key to continue . . . </code></pre><hr><p>примечание. если вы установите переменную в операторе <code>if ( ) else ( )</code>, она не будет доступна для defined до тех пор, пока она не выйдет из оператора «if» (если только не включено «delayed variable expansion»; после включения используйте восклицательный знак «!» вместо символ процента "%"}.</p><p>например:</p><h1>сценарий 2:</h1><p>ввод («удалить цитаты. cmd» «это тест»)</p><pre><code>@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 </code></pre><p>результат:</p><pre><code>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> </code></pre><hr><p>примечание: он также удалит кавычки внутри строки.</p><p>например (используя скрипт 1 или 2): c:\users\test\documents\batch files> "удалить quotes.cmd" "это" a "тест"</p><p>вывод (сценарий 2):</p><pre><code>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 </code></pre><hr><p>выполнить («удалить quotes.cmd») без каких-либо параметров в сценарии 2:</p><p>результат:</p><pre><code>welcome! press any key to continue . . . </code></pre>

<p>ты можешь использовать </p><pre><code>if defined (variable) echo that's defined! if not defined (variable) echo nope. undefined. </code></pre>

<p>я обычно использую это:</p><pre><code>if "%1."=="." goto mylabel </code></pre><p>если% 1 пуст, if сравнивает "." к "." который оценит как истину.</p>

<p>я тестирую с кодом ниже, и это нормально.</p><pre><code>@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 ) </code></pre>

<p>я создал этот небольшой пакетный скрипт на основе ответов здесь, так как есть много действительных. не стесняйтесь добавлять к этому, если вы придерживаетесь того же формата:</p><pre><code>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 </code></pre>

<p>подводя итог:</p><pre><code>set str=%~1 if not defined str ( echo empty string ) </code></pre><p>этот код выведет «пустую строку», если% 1 либо «», либо «или пусто. добавил его к принятому ответу, который в настоящее время неверен.</p>

<p>с помощью ! вместо "для проверки пустой строки</p><pre><code>@echo off set a= set b=hello if !%a%! == !! echo string a is empty if !%b%! == !! echo string b is empty </code></pre>

<p>у меня было много вопросов с большим количеством ответов в сети. большинство работает для большинства вещей, но всегда есть угловой случай, который ломает каждый.<br/> возможно, это не сработает, если у него есть кавычки, может быть, оно сломается, если у него нет кавычек, синтаксическая ошибка, если у переменной есть пробел, некоторые будут работать только с параметрами (в отличие от переменных среды), другие методы позволяют пустому набору цитат проходить как «определенные», а некоторые более хитрые не позволят вам связать <code>else</code> впоследствии.</p><p>вот решение, которым я доволен, пожалуйста, дайте мне знать, если вы найдете угловой корпус, для которого он не будет работать.</p><pre class="lang-dos prettyprint-override"><code>:ifset if "%~1"=="" (exit /b 1) else (exit /b 0) </code></pre><p>наличие этой подпрограммы либо в вашем скрипте, либо в его собственном <code>.bat</code>, должно работать.<br/> итак, если вы хотите написать (псевдо):</p><pre class="lang-dos prettyprint-override"><code>if (var) then something else somethingelse </code></pre><p>ты можешь написать:</p><pre class="lang-dos prettyprint-override"><code>(call :ifset %var% && ( echo something )) || ( echo something else ) </code></pre><hr><p>это сработало для всех моих тестов:</p><pre class="lang-dos prettyprint-override"><code>(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 </code></pre><p>echo'd <code>n</code>, <code>y</code>, <code>n</code>, <code>y</code>, <code>y</code></p><hr><p>больше примеров:</p><ul> <li>хотите просто проверить <code>if</code>? <code>call :ifset %var% && echo set</code></li> <li>просто если нет (только остальное)? <code>call :ifset %var% || echo set</code></li> <li>проверка переданного аргумента; работает отлично. <code>call :ifset %1 && echo set</code></li> <li>не хотите засорить ваш код сценариев/дублирования, поэтому вы поместили его в свой собственный <code>ifset.bat</code>? нет проблем: <code>((call ifset.bat %var%) && echo set) || (echo not set)</code></li> </ul>

<p>я вошел чуть меньше месяца назад (хотя об этом спросили 8 лет назад) ... я надеюсь, что он/она уже перешел за пределы пакетных файлов. ; -) раньше я делал это все время. я не уверен, какова конечная цель, хотя. если он/она ленив, как я, мой go.bat работает на такие вещи. (см. ниже) но, 1, команда в op может быть недействительной, если вы непосредственно используете ввод как команду. т.е. </p><pre><code>"c:/users/me" </code></pre><p>является неверной командой (или использовалась, если вы были на другом диске). вам нужно разбить его на две части.</p><pre><code>c: cd /users/me </code></pre><p>и, 2, что означает «определенный» или «неопределенный»? gigo. я использую по умолчанию, чтобы ловить ошибки. если ввод не перехватывается, он падает, чтобы помочь (или команда по умолчанию). таким образом, без ввода не является ошибкой. вы можете попробовать перейти на вход и поймать ошибку, если она есть. (хорошо, использование загрузок go (только один парень) перехватывается dos. (сурово!))</p><pre><code>cd "%1" if %errorlevel% neq 0 goto :error </code></pre><p>и, 3, кавычки нужны только вокруг пути, а не команды. т.е. </p><pre><code>"cd c:\users" </code></pre><p>было плохо (или раньше), если только вы не были на другом диске. </p><pre><code>cd "\users" </code></pre><p>функционально.</p><pre><code>cd "\users\dr whos infinite storage space" </code></pre><p>работает, если у вас есть пробелы на вашем пути. </p><pre><code>@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 </code></pre>