2012-02-23 65 views
1

下面的脚本应该管理添加和删除条目到主机文件。 .dev条目应该指向本地主机,所有其他应提示输入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 [email protected]:jamonholmgren/%domain%.git %sitespath%\%domain%\ 
    pause 
) else (
    echo Okay, then we're done. 
    pause 
) 

回答

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 (

您有%去除相同延迟扩展问题%

编辑 - 扩大对舍甫琴科M的评论

您对ip和删除的用户输入处理方式也存在潜在问题。在提示值之前,这两个值都应该初始化为无或默认值。如果用户没有输入任何内容,则保留现有的默认值(如果有的话)。

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

+1

我想'ip'也必须做出不确定的在开始的地方(后'SETLOCAL ...'可能),只是为了当'如果定义的IP ...'调用安全起见,以防用户已经按下Enter键而没有输入任何内容。 – 2012-02-23 07:32:25

+0

@AndriyM - 是的,我看到了。我认为验证输入值可能比初始化值更重要。我很懒,并没有谈论它,但我现在要修改答案。 – dbenham 2012-02-23 12:39:07

0

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

  • cmd shell启动,以避免退出

  • 添加更多REM命令,将作为日志后关闭窗口车削时的条目echo on

  • 通过反复删除零件来简化脚本结束直到它没有错误地运行。重新插入故障零件,并尝试找出什么是错在那里

虽然这并不完全回答你的问题,我希望提示将帮助您解决问题。欢迎您随时询问一般性建议,但恐怕您的特定问题有点过于具体,不能引起广泛关注。

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%。例如:

if %ip% (

,我敢肯定的是,问题所在行...

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 [email protected]:jamonholmgren/%domain%.git %sitespath%\%domain%\ 
    pause 
) else (
    echo Okay, then we're done. 
    pause 
)