【问题标题】:Batch File - Hosts file editor - prevent duplicate entries - delete previously added entries批处理文件 - 主机文件编辑器 - 防止重复条目 - 删除以前添加的条目
【发布时间】:2019-02-26 23:56:11
【问题描述】:

好的,这就是我到目前为止所得到的。 这意味着在主机文件中添加要阻止的网站,并允许用户在需要时删除条目。有时尝试添加要阻止的网站时,它会创建一个新行,然后将条目放在它之前的行上。这不是我想要的。我希望它创建一个新行,然后在该行上添加条目。出于某种原因,它有时会起作用,而有时它根本不起作用。我收到一条错误消息,指出 Find 参数不正确。我正在使用 Find 命令查看条目是否已在 hosts 文件中。如果是,我希望它避免添加它。如果不是,那么我想添加它。当我尝试删除一个条目时,批处理会崩溃,所以我不确定我在这里做错了什么。我正在尝试找到该条目并将其替换为任何内容。我真正想做的是删除整行,这样我就不会得到很多空行。 任何帮助是极大的赞赏。谢谢!

@echo off
TITLE Modifying your HOSTS file
COLOR F0

:LOOP
cls
SET "CHOICE="
ECHO Choose 1 to block a website 
ECHO Choose 2 remove a blocked website 
ECHO Choose 3 to exit
SET /P CHOICE= selection %CHOICE%
GOTO %CHOICE%

:1
cls
SET /P WEBSITE=Enter the name of the website to add:
SET HOME=     127.0.0.1 
SET NEWLINE=^& echo.
SET BLOCKEDSITE=%HOME% %WEBSITE%

FIND /C /I %BLOCKEDSITE% %WINDIR%\system32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 0 ECHO %NEWLINE%^%BLOCKEDSITE%>>%WINDIR%\System32\drivers\etc\hosts
ECHO Website blocked
ping 127.0.0.1 -n 5 > nul
GOTO LOOP

:2
cls
SET /P WEBSITE=Enter the name of the website to remove:

SETLOCAL ENABLEEXTENTIONS DISABLEDELAYEDEXPANSION

SET "HOME=     127.0.0.1 "
SET "BLOCKEDSITE=%HOME% %WEBSITE%"
SET "REPLACE="
SET "HOSTSFILE=%WINDIR%\system32\drivers\etc\hosts"

FOR /F "DELIMS=" %%i IN ('TYPE "%HOSTSFILE%" ^& BREAK ^> "%HOSTSFILE%" ') 
DO 
(
    SET "LINE=%%i"
    SETLOCAL ENABLEDELAYEDEXPANSION
    >>"%HOSTSFILE%" echo(!LINE:%BLOCKEDSITE%=%REPLACE%!
    ENDLOCAL
)

ECHO Website unblocked

GOTO LOOP

:3
EXIT

【问题讨论】:

  • 那么哪一行会产生错误信息呢?请阅读Debugging batch filesedit 您的问题。
  • 几乎所有文本编辑器中的“查找/替换”功能都可以更简单直接地执行该过程,尤其是那些接受“正则表达式”术语的编辑器。我认为没有理由通过使用批处理文件、允许不受控制的最终用户输入和写入临时文件来使过程更加困难或冗长。

标签: batch-file batch-processing


【解决方案1】:

请注意,website 一词在引用 hosts 文件的条目时具有误导性。 hosts 文件的条目用于自定义 DNS 主机名到 IP 地址的映射,并且文件中存在的任何主机名不一定托管网站。使用术语website 可能会导致错误印象,即可以将http://www.example.com 之类的内容添加到主机文件中,这是不正确的。

如果主机文件中已存在主机,则跳过它:
您使用 find 的问题是 %BLOCKEDSITE% 有嵌入的空格,因此您应该将其括起来并使用:

FIND /C /I "%BLOCKEDSITE%" %WINDIR%\system32\drivers\etc\hosts

但它还有另一个问题:由于它依赖于%BLOCKEDSITE% 规定的 IP 地址和主机名之间的确切间距,它仅适用于您的批处理文件添加的条目。此外,用户可能已通过在包含条目的行的开头放置 # 来注释掉(禁用)条目,即使条目被禁用,您的批处理代码也将跳过添加主机。

这可以通过使用带有正则表达式语法的findstr 来解决。例如:

findstr /IRC:"^ *127\.0\.0\.1 *example\.com *$" "%WINDIR%\system32\drivers\etc\hosts"

从 hosts 文件中删除一个条目:
FOR 循环中,您只需跳过写入包含指定条目的行:

if "!Line!"=="!LINE:%BLOCKEDSITE%=!" echo(!Line!>>"%HOSTSFILE%"

但它还是不准确,并且遇到了前面提到的跳过添加条目的相同问题。再次使用findstr,您可以轻松删除包含不需要的条目的行:

findstr /VIRC:"^ *127\.0\.0\.1 *example\.com *$" "%HOSTSFILE%" > "%HOSTSFILE%.tmp"
del "%HOSTSFILE%"
ren "%HOSTSFILE%.tmp" "hosts"

根据上述几点,脚本可以改写成这样:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
title Modifying your HOSTS file
color F0

set "HOSTSFILE=%WINDIR%\system32\drivers\etc\hosts"
set "HOME=127.0.0.1"
set "PROMPT_TEXT=Enter the host name to"
set "ACTION_TEXT[1]=add"
set "ACTION_TEXT[2]=remove"
set "FindEmptyLine=^ *$"
set "NewLineAppended="
cls
setlocal EnableDelayedExpansion
:LOOP
echo,
echo 1. Block a host
echo 2. Remove a blocked host
echo 3. Exit
choice /C "123" /N /M "Choose an item [1, 2, 3]: "
set "Item=%errorlevel%"

goto choice%Item%

:choice0 // User Pressed CTRL-C
:choice3
exit /b

:choice1
call :Common
set "HostEntry=!HOME! !HOST!"
findstr /IRC:"!FindEntry!" "!HOSTSFILE!"> nul && (
    echo The host !HOST! is already blocked, No action taken.
) || (
    if not defined NewLineAppended (
        REM This will append a new line ONLY if the file does not end by LF character
        type "!HOSTSFILE!" | findstr $ > "!HOSTSFILE!.tmp" && (
            del "!HOSTSFILE!"
            ren "!HOSTSFILE!.tmp" "hosts"
            set "NewLineAppended=1"
        )
    )
    echo !HostEntry!>>"!HOSTSFILE!"
    echo The host !HOST! blocked
)
goto LOOP

:choice2
call :Common
findstr /VIR /C:"!FindEntry!" /C:"!FindEmptyLine!" "!HOSTSFILE!">"!HOSTSFILE!.tmp" && (
    del "!HOSTSFILE!"
    ren "!HOSTSFILE!.tmp" "hosts"
    echo The host !HOST! unblocked
)
goto LOOP

:Common
set "HOST="
set /P "HOST=!PROMPT_TEXT! !ACTION_TEXT[%Item%]! (e.g. example.com): "
if not defined HOST (
    (goto)2>nul
    goto LOOP
)
set "FindEntry=^^ *!HOME! *!HOST! *$"
set "FindEntry=!FindEntry:.=\.!"
exit /b

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    相关资源
    最近更新 更多