Синтаксис команды неверен? - PullRequest
0 голосов
/ 03 декабря 2018

Я новичок в партии, и поэтому не могу понять, почему я получаю синтаксическую ошибку ??

Это мой код:

set /p hostname1=<a.txt


echo %hostname1%

PAUSE

IF %hostname1% == 0 (
    SET %hostname02% = 1
    echo %hostname02% >> a.txt
    PAUSE

) 

IF %hostname1% == 1 (

    SET %hostname03% = 2
    echo %hostname03% >> a.txt
    PAUSE
    exit
) 

IF %hostname1% == 2 (
    echo MSGBOX "Message" > %temp%\TEMPmessage.vbs
    call %temp%\TEMPmessage.vbs
    del %temp%\TEMPmessage.vbs /f /q
) 

Этопросто проект "для удовольствия", но я хотел бы понять, почему я получаю эту досадную ошибку!

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Во-первых, прочитайте ответ на Почему нет строкового вывода с 'echo% var%' после использования 'set var = text' в командной строке? Объясняется, как правильно присвоить строковое значение средепеременная.Неверное значение set variable = value, которое присваивает ПРОБЕЛ значение переменной среды с именем переменная ПРОБЕЛ , и по этой причине отсутствует переменная средыс именем переменная после этой командной строки.

Совершенно неверно, в большинстве случаев также set %variable%=value, поскольку из-за этой командной строки значение присваивается переменной среды с именемопределяется значением переменной среды переменной .


Во-вторых, все ссылки на переменные среды выполняются с синтаксисом %variable% в блоке команд, начинающемся с ( и заканчивающиеся соответствием ) расширяются на текущее значение переменной среды перед тем, как команда, использующая командный блок, будет выполнена вообще.Это означает, что все %variable% заменены текущим значением указанной переменной среды, которое является ничем, если переменная с именем переменная еще не определена.

Давайте посмотрим, что на самом делевыполняется cmd.exe для командного блока, например:

set "hostname02="
set "hostname1=0"

IF %hostname1% == 0 (
    SET %hostname02% = 1
    echo %hostname02% >> a.txt
    PAUSE
)

Реально выполняемыми командными строками являются:

set "hostname02="
set "hostname1=0"
IF 0 == 0 (
SET  = 1
 echo   1>>a.txt
 PAUSE
)

Результатом является завершение выполнения командного файла cmd.exeс сообщением об ошибке:

Синтаксическая ошибка.

Это можно увидеть, запустив пакетный файл без @echo off или с @echo ON из окна командной строки.вместо двойного щелчка на командном файле.См. Также отладка пакетного файла .

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


Рабочий код для рассматриваемого примера кода:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
if exist a.txt set /P hostname1=<a.txt
if not defined hostname1 set "hostname1=0"
echo hostname1 is: %hostname1%

if "%hostname1%" == "0" (
    set hostname02=1
    >>a.txt echo 1
) else if "%hostname1%" == "1" (
    set hostname03=2
    >>a.txt echo 2
    goto EndBatch
) else if "%hostname1%" == "2" (
    echo MSGBOX "Message">"%TEMP%\TEMPmessage.vbs"
    %SystemRoot%\System32\wscript.exe "%TEMP%\TEMPmessage.vbs"
    del "%TEMP%\TEMPmessage.vbs"
)

:EndBatch
endlocal
pause

Этот пакетный файл сначала устанавливает локальную среду с включенными расширениями команд, как требуется здесь, и отложенным расширением переменных среды, отключенным, как не требуется приведенным ниже кодом.Параметры EnableExtensions DisableDelayedExpansion при использовании команды setlocal могут быть опущены, поскольку расширения команд включены по умолчанию и отложенное расширение по умолчанию отключено при запуске нового командного процесса, как это делается при двойном щелчке по пакетному файлу.Но всегда желательно явно определить среду, необходимую для пакетного файла.Прочитайте этот ответ для получения подробной информации о командах SETLOCAL и ENDLOCAL .

Следующая строка назначает первую строку файла a.txt переменной средыhostname1 если этот файл вообще существует в текущем каталоге, что, конечно, может отличаться от каталога пакетного файла, в зависимости от того, как пакетный файл был запущен для выполнения с помощью cmd.exe.

Команда FOR с параметром /F обычно используется для построчного чтения текстового файла и назначения строк, считанных из файла, переменным среды.Но set /P variable=<file.txt также можно использовать для назначения первой строки file.xt переменной окружения variable.

Четвертая командная строка проверяет, определена ли теперь переменная hostname1, что не так, еслифайл a.txt не существует в текущем каталоге или этот файл начинается с пустой строки.Переменная среды hostname1 определяется со значением 0, если она не определена после третьей строки.

Далее для визуальной проверки выводится текущее значение переменной hostname1.

Затем три IF условия используются для сравнения строк с учетом регистра.Строки для сравнения заключены в двойные кавычки, что делает пакетный файл более отказоустойчивым против выхода из-за синтаксической ошибки в зависимости от строки, прочитанной из файла a.txt.Но это решение все еще не на 100% отказоустойчиво, см. Ответ на Как остановить интерпретатор команд Windows от завершения выполнения пакетного файла при неправильном вводе пользователем? для получения подробной информации о том, как получить код отказоустойчивого пакетного файла наиспользование set /P со строковым значением, введенным пользователем или считанным из файла, который каждый пользователь может редактировать перед запуском пакетного файла.

Строковые значения, присвоенные hostname02 и hostname03, фиксируются в кодеи, следовательно, эти строковые значения могут быть непосредственно записаны также в файл a.txt без необходимости ссылаться на переменные окружения hostname02 и hostname03, определенные внутри командных блоков, что потребовало бы отложенного расширения переменной окружения.

оператор перенаправления >> и имя файла записываются в начале строки для реальной записи в файл a.txt просто 1 или 2 без завершающего пробела, если на этих двух echo нет завершающих пробеловкомандные строки в командном файле.При использовании echo 1 >>a.txt пробел между 1 и >> также будет записан в файл a.txtecho 1>>a.txt вообще не будет записывать 1 в файл a.txt.Подробнее читайте в статье Microsoft о Использование операторов перенаправления команд .Командный процессор Windows переформатирует >>a.txt echo 1 в echo 1 1>>a.txt перед выполнением этой командной строки.Так >>a.txt в начале строки после пробелов отступа для лучшей читабельности перемещается интерпретатором команд Windows при разборе в конец командной строки с добавлением 1 (пробел и один) слева для перенаправленияoperator >>.

VBScript выполняется либо с cscript.exe - консольной версией хоста скриптинга Windows - либо с wscript.exe - GUI версией хоста скриптинга Windows.Команда CALL не подходит для выполнения сценария VBScript.Таким образом, пакетный файл использует wscript.exe для запуска сценария VBScript с простым окном сообщения.

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

  • del /?
  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • pause /?
  • set /?
  • setlocal /?
  • wscript /?
0 голосов
/ 03 декабря 2018
set /p hostname1=<a.txt


echo %hostname1%

PAUSE

:: this will check if the string hostname1 is "0"
IF "%hostname1%" == "0" (
    SET "hostname02=1"
    echo !hostname02! >> a.txt
    PAUSE

) 

IF %hostname1% == 1 (

    SET "hostname03=2"
    echo !hostname03! >> a.txt
    PAUSE
    exit
) 

IF %hostname1% == 2 (
    echo MSGBOX "Message" > %temp%\TEMPmessage.vbs
    call %temp%\TEMPmessage.vbs
    del %temp%\TEMPmessage.vbs /f /q
)

попробуй вот так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...