V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Foxkeh
V2EX  ›  程序员

请问这个维护 hosts 文件的 bat 哪里写的不对?

  •  1
     
  •   Foxkeh · 3 天前 · 1022 次点击

    自己喜欢折腾 hosts 文件,比如下面这是 Postman7 系列最终版屏蔽更新用的. 目前已经可以通过 PowerShell 可以正常维护 hosts 文件 虽然 PowerShell 更方便语法也更简洁,但是需要额外执行一次 set-ExecutionPolicy RemoteSigned 才可以运行脚本感觉还是有点麻烦,所以还是折腾下 bat 脚本文件, 但是输出有问题但不知道出在哪

    @echo off
    setlocal enabledelayedexpansion
    chcp 65001 > nul
    
    :: 提权到管理员权限
    net session >nul 2>&1
    if %errorlevel% neq 0 (
        echo Requesting administrative privileges...
        powershell -Command "Start-Process '%~0' -Verb runAs"
        exit /B
    )
    
    :: 定义要添加的规则列表
    set "rules[0]=127.0.0.1    dl.pstmn.io"
    set "rules[1]=127.0.0.1    onboarding.postman.com"
    set "rules[2]=127.0.0.1    analytics.getpostman.com"
    set "rules[3]=127.0.0.1    assets.getpostman.com"
    set "rules[4]=127.0.0.1    static.getpostman.com"
    set "rules[5]=127.0.0.1    skills.gw.postman.com"
    set "rules[6]=127.0.0.1    skills-assets.pstmn.io"
    set "rules[7]=127.0.0.1    skills.getpostman.com"
    set "rules[8]=127.0.0.1    config.getpostman.com"
    set "rules[9]=127.0.0.1    cdn.postman.com"
    set "rules[10]=127.0.0.1    getpostman.com"
    set "rules[11]=127.0.0.1    www.postman.com"
    set "rules[12]=#127.0.0.1   identity.getpostman.com"
    set "rules[13]=#127.0.0.1   sync-v3.getpostman.com"
    
    
    :: 设置 hosts 文件路径
    set "hostsFile=%windir%\System32\drivers\etc\hosts"
    
    :: 备份原始 hosts 文件
    copy "%hostsFile%" "%hostsFile%.bak" >nul
    
    :: 移除 hosts 文件的只读属性
    attrib -R "%hostsFile%"
    :: 读取每条规则并进行处理
    for %%a in (0,1,13) do (
        set "line=!rules[%%a]!"
        echo Current: !line!
        :: 检查该规则是否已存在于 hosts 文件中
        findstr /C:"!line!" "%hostsFile%" >nul
        if errorlevel 1 (
            :: 如果未找到,则添加到 hosts 文件
            echo !line! >> "%hostsFile%"
            echo Added: !line!
        ) else (
            echo Skipped: !line! already exists
        )
    )
    
    :: 重新添加 hosts 文件的只读属性
    attrib +R "%hostsFile%"
    
    echo Done.
    endlocal
    pause
    

    不知道为啥一共 13 条记录输出界面只打印下面 3 条,相应的 hosts 文件里也只出现了这三条, 百思不得其解, 求指教

    Current: 127.0.0.1    dl.pstmn.io
    Skipped: 127.0.0.1    dl.pstmn.io already exists
    Current: 127.0.0.1    onboarding.postman.com
    Skipped: 127.0.0.1    onboarding.postman.com already exists
    Current: #127.0.0.1   sync-v3.getpostman.com
    Skipped: #127.0.0.1   sync-v3.getpostman.com already exists
    Done.
    Press any key to continue . . .
    
    11 条回复    2024-11-27 21:49:55 +08:00
    FrankFang128
        1
    FrankFang128  
       3 天前
    问 AI 吧
    javalaw2010
        2
    javalaw2010  
       3 天前
    虽然我不懂 bat 语法,但是根据你的代码和输出,我猜应该是 for %%a in (0,1,13)这句的问题
    javalaw2010
        3
    javalaw2010  
       3 天前   ❤️ 1
    刚查了下,也许你应该使用 for /l 语法。
    Foxkeh
        4
    Foxkeh  
    OP
       3 天前
    @FrankFang128 问过 AI 了,这个脚本都是 AI(chatgpt 和讯飞星火)帮助生成的,我完全不会 bat 语法
    cc666
        5
    cc666  
       3 天前   ❤️ 1
    for /L %%a in (0,1,13) do (
    wwwz
        6
    wwwz  
       3 天前   ❤️ 1
    问题点 1:for 循环范围错误
    for %%a in (0,1,13) 的写法实际上会将 (0,1,13) 作为一个单独的列表处理,而不是逐步迭代 0 到 13 。

    解决办法:应使用一个范围循环或明确列出需要的索引:

    for /L %%a in (0,1,13) do (
    或:

    for %%a in (0 1 2 3 4 5 6 7 8 9 10 11 12 13) do (
    tangtang666
        7
    tangtang666  
       3 天前   ❤️ 1
    直接用 switchhosts 这个软件就行
    niuin969
        8
    niuin969  
       3 天前   ❤️ 1
    PowerToys 也可以
    bluforduwjldz1
        9
    bluforduwjldz1  
       3 天前   ❤️ 1
    问题出在 for 循环的范围设置上。在您的代码中:

    batch

    复制
    for %%a in (0,1,13) do
    这行代码只会循环 3 次,分别处理索引 0 、1 和 13 的规则。在批处理中,这种写法不会遍历 0 到 13 之间的所有数字。

    要遍历所有 13 条规则,您可以使用以下修改后的代码:
    ```bash
    @echo off
    setlocal enabledelayedexpansion
    chcp 65001 > nul

    :: 提权到管理员权限
    net session >nul 2>&1
    if %errorlevel% neq 0 (
    echo Requesting administrative privileges...
    powershell -Command "Start-Process '%~0' -Verb runAs"
    exit /B
    )

    :: 定义要添加的规则列表
    set "rules[0]=127.0.0.1 dl.pstmn.io"
    set "rules[1]=127.0.0.1 onboarding.postman.com"
    set "rules[2]=127.0.0.1 analytics.getpostman.com"
    set "rules[3]=127.0.0.1 assets.getpostman.com"
    set "rules[4]=127.0.0.1 static.getpostman.com"
    set "rules[5]=127.0.0.1 skills.gw.postman.com"
    set "rules[6]=127.0.0.1 skills-assets.pstmn.io"
    set "rules[7]=127.0.0.1 skills.getpostman.com"
    set "rules[8]=127.0.0.1 config.getpostman.com"
    set "rules[9]=127.0.0.1 cdn.postman.com"
    set "rules[10]=127.0.0.1 getpostman.com"
    set "rules[11]=127.0.0.1 www.postman.com"
    set "rules[12]=#127.0.0.1 identity.getpostman.com"
    set "rules[13]=#127.0.0.1 sync-v3.getpostman.com"

    :: 设置 hosts 文件路径
    set "hostsFile=%windir%\System32\drivers\etc\hosts"

    :: 备份原始 hosts 文件
    copy "%hostsFile%" "%hostsFile%.bak" >nul

    :: 移除 hosts 文件的只读属性
    attrib -R "%hostsFile%"

    :: 读取每条规则并进行处理
    for /L %%a in (0,1,13) do (
    set "line=!rules[%%a]!"
    echo Current: !line!
    :: 检查该规则是否已存在于 hosts 文件中
    findstr /C:"!line!" "%hostsFile%" >nul
    if errorlevel 1 (
    :: 如果未找到,则添加到 hosts 文件
    echo !line! >> "%hostsFile%"
    echo Added: !line!
    ) else (
    echo Skipped: !line! already exists
    )
    )

    :: 重新添加 hosts 文件的只读属性
    attrib +R "%hostsFile%"

    echo Done.
    endlocal
    pause
    ```

    主要修改是将:

    ```bash
    for %%a in (0,1,13) do
    ```
    修改为
    ```bash
    for /L %%a in (0,1,13) do
    ```

    使用 /L 参数后,格式为 (start,step,end),这样会从 0 开始,每次加 1 ,一直到 13 ,从而处理所有的规则。这样修改后,脚本将会处理所有 14 条规则(索引 0 到 13 )。
    Foxkeh
        10
    Foxkeh  
    OP
       3 天前
    @javalaw2010
    @cc666
    @wwwz
    @bluforduwjldz1
    多谢多谢各位大侠指点[手动抱拳]
    xqzr
        11
    xqzr  
       3 天前
    @Livid #6 #9 AI
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1068 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:23 · PVG 03:23 · LAX 11:23 · JFK 14:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.