【问题标题】:This code does not run but only exits. I am not sure where I have made a mistake此代码不会运行,只会退出。我不确定我在哪里犯了错误
【发布时间】:2020-02-09 18:05:03
【问题描述】:

我希望你能帮助我。所以,我一直在尝试运行这个命令。但是每次我这样做..它都会退出。然后,我发现这个错误..“批处理文件do(此时是意外的”我不确定我在哪里犯了错误。提前感谢所有回复。

这是我的代码:

@echo off
for /L %%n in (1,1,3) do (
    set uname=mama 
    set pword=mu

    :xy
    set /p user ="Enter Username"
    set /p pass="Enter Pass"
    if %uname%==%user% ( echo 
        username is valid ) ELSE (
        echo username not found
        goto xy
    )
    IF %pword%==%pass% ( echo sucess 
    ) ELSE (
        echo invalid password
        goto xy
    )
    pause
    if %%n EQU 3 (echo Run Again)
)

【问题讨论】:

标签: batch-file


【解决方案1】:

这是基于 @Stephan cmets 详细阐述的:

_cnt 计数器替换 for 循环以限制 if 的尝试。


@echo off && setlocal enabledelayedexpansion 

set "uname=mama" && set "pword=mu"

:xy

set /a "_cnt+=1+0" && set /p "user=Enter Username: "

if not !_cnt! EQU 3 (

   if "!uname!" == "!user!" (echo/ Username is valid^!! 
       ) else ( echo/ Username not found^!! & goto :xy )

   set /p "pass=Enter Pass: " 

   if "!pword!" == "!pass!" (echo/ Sucess^!! 
       ) else ( echo/ Invalid password^!! & goto :xy )

   ) else ( echo/ Run Again^!! && %__APPDIR__%timeout -1 & endlocal &  goto :EOF )

rem./ do more tasks here... after use endlocal ... && endlocal & goto :EOFF

【讨论】:

    【解决方案2】:

    您的代码中有一些错误。

    1. 代码块中不允许使用标签,标签可能会破坏它们。 // 标签被移除。
    2. goto 无条件破坏代码块 // 留下一个 goto 故意离开循环并删除其余部分
    3. 您需要delayed expansion 才能使用在同一代码块中更改的变量(unamepword 技术上不需要,因为我在循环之外定义了它们)//启用并使用延迟扩展
    4. set uname=mama<space> 中有一个空格 // 已通过推荐语法修复 set "var=value"
    5. (安全问题)出于安全原因,您不应该知道是用户名还是密码(或两者),这是错误的。 // 已修复(作为奖励,它简化了代码)

    修复上述错误并降低代码复杂度后,它可能如下所示:

    @echo off
    setlocal enabledelayedexpansion
    set "uname=mama"
    set "pword=mu"
    for /L %%n in (1,1,3) do (
        set /p "user=Enter Username: "
        set /p "pass=Enter Password: "
        if "!uname!-!pword!" == "!user!-!pass!" goto :payload
        echo Invalid username or password.
        pause
    )
    echo sorry, run again.
    goto :eof
    
    :payload
    echo successfully logged in.
    REM rest of your code
    

    (说到安全性:在(可读)代码中以明文形式提供凭据在任何标准上都不安全,但使用纯批处理很难克服)

    【讨论】:

      【解决方案3】:

      查看您的代码,在我看来,使用 Call 可以解决嵌套标签和延迟扩展问题,并且可能使您的代码更易于管理

      @Echo Off
      Set "uname=mama"
      Set "pword=mu"
      Set "user="
      Set "pass="
      
      :Inputs
      For /L %%G In (1,1,3) Do (
          Call :xy
          If Not ErrorLevel 1 GoTo Main
      )
      "%__AppDir__%choice.exe" /M "Would you like to try again"
      If Not ErrorLevel 2 GoTo Inputs
      Exit /B 1
      
      :Main
      Rem Your code below here for users with successful inputs.
      Echo Welcome %user%.
      Timeout /T 3 /NoBreak > NUL
      Rem Your code ends above here.
      Exit /B 0
      
      :xy
      ClS
      Set /P "user=Enter Username> %user%"
      If /I Not "%uname%" == "%user%" (
          Echo Username not found.
          Set "user="
          Timeout /T 2 /NoBreak > NUL
          Exit /B 1
      )
      Echo Username is valid.
      Set /P "pass=Enter Pass> "
      IF "%pword%" == "%pass%" Exit /B 0
      Echo Invalid password.
      Set "pass="
      Timeout /T 2 /NoBreak > NUL
      Exit /B 1
      

      您可能会注意到,我使用了推荐的语法来使用Set 命令定义变量。它确保内容受到保护并且没有隐藏尾随空格之类的东西。如果您查看问题中的代码,您会注意到分配给uname 变量的值实际上是mama<space>。当mama 被锁定在脚本的其余部分之外时,这显然会导致问题!

      您还注意到在 echousername is valid 之间有一个不需要的换行符而不是空格。

      编辑

      对上面的代码进行了重新设计,最多允许尝试三次正确输入两个值,虽然try again 消息似乎有点多余

      【讨论】:

      • 强制用户在执行有效负载之前输入有效凭据 3 次。
      • 老实说@Stephan,我什至没有考虑过允许最终用户只尝试三次才能使两个条目都正确。对于我的误解,我深表歉意,并已重新编写代码以解决此问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 2015-02-03
      • 2021-01-22
      • 1970-01-01
      • 2013-09-06
      • 2017-05-10
      • 2022-08-02
      相关资源
      最近更新 更多