批处理文件添加/删除主机文件条目语法错误

时间:2012-02-23 01:35:36

标签: dos batch-file

以下脚本应该管理在hosts文件中添加和删除条目。带有.dev的条目应该指向localhost,其他所有条目都应该提示输入IP地址。如果该条目已存在,则应询问您是否要将其删除。

我收到一个模糊的The syntax of the command is incorrect错误,但我不确定它指的是哪一行。如果我在其上转@echo然后在下一行吐出if (然后就死了。我能捕捉错误的唯一方法是做一个截图,因为它会立即退出。

我花了几个小时的时间,所以非常感谢任何帮助!

@echo off

title ClearSight Studio
echo Virtual website setup script
echo Version 1.4
echo Last modified 12/30/2011
echo.

REM Get the name of the domain name
echo What domain name? Ctrl+C to cancel. Example: newdomain.dev.
set /p domain= Domain:

REM Set a variable for the Windows hosts file location
set hostpath=\windows\system32\drivers\etc
set hostfile=hosts
set sitespath=\clearsight\sites
set extension=%domain:~-3%

REM Make the hosts file writable
attrib -r %hostpath%\%hostfile%

REM Add the domain to point to localhost at the end of the file if it doesn't already have an entry.
find /c "   %domain%" %hostpath%\%hostfile%
if errorlevel 1 (
    if /i %extension%==dev (
        set /p ip= What is the IP?
    )
    echo. >> %hostpath%\%hostfile%
    echo.# Adding %domain% via batch process on %date:~10,4%-%date:~4,2%-%date:~7,2%. >> %hostpath%\%hostfile%
    if %ip% (
        echo.%ip%       %domain% >> %hostpath%\%hostfile%
    ) else (
        echo.127.0.0.1      %domain% >> %hostpath%\%hostfile%
    )
) else if errorlevel 0 (
    echo Entry found in hostfile already. Would you like to remove it?
    set /p remove= Remove (Y/N)
    if /i %remove%==Y (
        findstr /v "%domain%" %hostpath%\%hostfile% > %hostpath%\%hostfile%
    )
)

if /i %extension%==dev (
    REM Create the folder if it doesn't exist
    if exist %sitespath%\%domain% (
        echo %sitespath%\%domain% already exists.
    ) else (
        echo Creating %sitespath%\%domain%...
        mkdir %sitespath%\%domain%
    )
)

REM Clean up
attrib +r %hostpath%\%hostfile%

echo. 
echo Done. 

if /i %extension%==dev (
    REM Do a "git" of the repo, if requested
    echo Would you like to clone an external git repository named %domain% from Bitbucket?
    echo This assumes the git repository was set up under the "jamonholmgren" account.
    echo Do it manually if it's under someone else's account. Also, make sure you have permissions to this repo.
    set /p getgit= Get git clone? (Y/N):
)

REM 
if /i %getgit%==Y (
    git clone git@bitbucket.org:jamonholmgren/%domain%.git %sitespath%\%domain%\
    pause
) else (
    echo Okay, then we're done.
    pause
)

4 个答案:

答案 0 :(得分:4)

这段代码有两个问题

if %ip% (
    echo.%ip%       %domain% >> %hostpath%\%hostfile%
) else (
  • 语法无效。我假设您要测试变量是否已定义。正确的语法是if defined ip (

  • 您正在尝试在定义它的同一if()块中展开%ip%。这不起作用,因为%ip%在分析时扩展,这是在您分配值之前!解决方案是使用延迟扩展而不是!ip!。首先必须使用setlocal enableDelayedExpansion

  • 启用延迟扩展,可能位于脚本顶部附近

所以固定代码看起来像这样

setlocal enableDelayedExpansion
.
.
.
if defined ip (
    echo.!ip!       %domain% >> %hostpath%\%hostfile%
) else (

%remove%

存在相同的延迟扩展问题

编辑 - 扩展Andriy M的评论

您还有一个潜在的问题,如何处理ip和删除的用户输入。在提示输入值之前,应将这两个值初始化为空或默认值。如果用户未输入任何内容,则保留现有的默认值(如果有)。

此外,您可能需要确认输入了有效值,尤其是对于ip。如果这样做,那么您将需要将提示从循环中取出并将其放入一个被调用的子例程中。子例程可以检查是否输入了值,如果不是,则循环返回再次尝试。它必须位于子程序中,因为您不能像在IF语句中那样使用带括号的代码块中的GOTO。

答案 1 :(得分:3)

当您通过%variable%展开变量值时,在读取包含命令的行之后和执行命令之前,它的值仅展开一次。例如:

set var=Original
set var=New & echo %var%

上一行显示“原始”。括号中包含的任何命令(属于任何IF或FOR命令)都会产生相同的效果。

解决此问题的方法是使用延迟变量扩展,将变量括在感叹号中而不是百分比:

set var=Original
set var=New & echo !var!

但是,您必须先使用以下命令激活延迟扩展:

setlocal EnableDelayedExpansion

因此,在程序开头插入前一行并更改对可能在IF或FOR by!name中更改其值的变量的所有引用!而不是%name%。例如:

if %ip% (

我确信是造成你问题的线......

答案 2 :(得分:3)

感谢大家的帮助!这是最终(工作)结果,以防任何人想要做类似的事情。屏幕输出可能会稍微调整一下,但在我的所有测试中看起来都非常可靠。

@echo off
setlocal enableDelayedExpansion

title ClearSight Studio
echo Virtual website setup script
echo Version 1.5
echo Last modified 2/23/2012
echo.

REM Get the name of the domain name
echo What domain name? Ctrl+C to cancel. Example: newdomain.dev.
set /p domain= Domain: 

REM Set a variable for the Windows hosts file location
set hostpath=\windows\system32\drivers\etc
set hostfile=hosts
set sitespath=\clearsight\sites
set extension=%domain:~-3%
REM Make the hosts file writable
attrib -r %hostpath%\%hostfile%

REM Add the domain to point to localhost at the end of the file if it doesn't already have an entry.
find /c "   %domain%" %hostpath%\%hostfile%
if errorlevel 1 (
    if /i NOT %extension%==dev (
        set /p ip= What is the IP? 
    ) else (
        set ip=127.0.0.1
    )
    echo. >> %hostpath%\%hostfile%
    echo.# Adding %domain% via batch process on %date:~10,4%-%date:~4,2%-%date:~7,2%. >> %hostpath%\%hostfile%
    echo.!ip!       %domain% >> %hostpath%\%hostfile%
) else if errorlevel 0 (
    echo Entry found in hostfile already.
    set /p remove= Would you like to remove it? (Y/N) 
    if /i !remove!==Y (
        findstr /v %domain% %hostpath%\%hostfile% > %hostpath%\%hostfile%.txt
        type %hostpath%\%hostfile%.txt > %hostpath%\%hostfile%
    )
)

if /i %extension%==dev (
    REM Create the folder if it doesn't exist
    if exist %sitespath%\%domain% (
        echo %sitespath%\%domain% already exists.
    ) else (
        echo Creating %sitespath%\%domain%...
        mkdir %sitespath%\%domain%
    )
)

REM Clean up
attrib +r %hostpath%\%hostfile%

REM Flush DNS so the changes are available imidiately
ipconfig /flushdns

echo. 
echo Done. 

if /i %extension%==dev (
    REM Do a "git" of the repo, if requested
    echo Would you like to clone an external git repository named %domain% from Bitbucket?
    echo This assumes the git repository was set up under the "jamonholmgren" account.
    echo Do it manually if it's under someone else's account. Also, make sure you have permissions to this repo.
    set /p getgit= Get git clone? (Y/N) 
)

REM 
if /i !getgit!==Y (
    git clone git@bitbucket.org:jamonholmgren/%domain%.git %sitespath%\%domain%\
    pause
) else (
    echo Okay, then we're done.
    pause
)

答案 3 :(得分:0)

调试批处理文件的一些提示:

  • cmd shell启动它以避免在退出后关闭窗口

  • 添加更多REM命令,在转为echo on

  • 时将用作日志条目
  • 通过反复删除末尾的部分直到它运行没有错误来简化您的脚本。重新插入有缺陷的部分并试图弄清楚那里有什么问题

虽然这不能完全回答你的问题,但我希望这些提示可以帮助你解决问题。我们随时欢迎您提出一般性建议,但我担心您的特定问题在某种程度上过于具体而无法引起普遍关注。