批处理文件显示提示不正确

时间:2015-10-29 14:03:51

标签: batch-file

以下batch存在两个问题。第一个是,当打开batch文件时,会向用户提示“y / n”问题:

问题1

Has the check been done

如果答案是“y”,则显示另一个“y / n”问题

问题2

Do you want to send the DOSE report

如果问题1的答案是“n”,则调用检查功能并显示另一个问题。但是,目前正在显示粗体的行,然后它将转到第二部分(再见函数)。我究竟做错了什么?谢谢你:)。

当前批次

@ECHO OFF
:: ask user 
 :choice
 set /P c=Has the check been done [y/n]
 if /i %c%==y (
 set /P c=Do you want to send the DOSE report[y/n]?
 ) else (
 if /i %c%==n goto check
 )
 if /i %c%==y ( 
"L:\NGS\HLA LAB\total quality management\QC & QA\DOSE reports\DOSE reporting form.xlsm"
 ) else (
 if /i %c%==n goto goodbye
 )
 :check
 set /P c=Do you want to perform the check [y/n]
 if /i %c%==y (
 echo "perform check and hit enter when complete" 
 pause goto choice
 )    else (
 if /i %c%==n goto goodbye
 :: count loop
 set var1=0
 :loop
 set /a var1=%var1%+1

 echo %var1%

 if %var1% EQU 1 (
 goto end
 ) else (
 goto loop
 )
 :end
 echo "the DOSE report has already been sent by %USERNAME% on %DATE% at   %TIME%"
 :goodbye
 echo "goodbye"
 TIMEOUT 2 /nobreak
 exit

2 个答案:

答案 0 :(得分:1)

First off, the if-else statement in :choice is missing its closing )

Heres an important note on user input, never trust it. Try putting something other than y/n in the first

:choice
set /p c=Has the check been done [y/n]
 if /i %c%==y (
   set /p c=Do you want to send the DOSE report[y/n]?
  ) else (
     if /i %c%==n goto check
)

If you input something invalid into the first if-else , say somebody tries typing no instead of n, it will fail to return them to :choice as it only checks for n or y

And end up running through script. In your case it fails the if statements before :check and starts :check's proccess, but in check the same issue arises, and it will run through to ::count loop and the following commands where it can mess up your data.

After each if-else statement, its VERY safe practice to add a default action, such as;

:choice
set /p c=Has the check been done [y/n]
 if /i %c%==y (
   set /p c=Do you want to send the DOSE report[y/n]?
  ) else (
    if /i %c%==n goto check
)

:[ If both if statements are false, it will reach this line: ]
cls
echo Error: "%c%" is not y/n.
pause
goto :choice

Another thing to note, if nothing is input, errors will occur. You can fix this by checking if the variable is defined right after set /p c=Has the check been done [y/n] using:

 if not defined c (
   cls
   echo Error: Input cannot be empty!
   pause
   goto :choice
)

So a proper way to do the first check would be:

:choice
set /p c=Has the check been done [y/n]
:[Empty check ]
if not defined c cls & echo Error: Input cannot be empty! & pause & goto :choice
 if /i "%c%==y" (
   set /p c=Do you want to send the DOSE report[y/n]?
  ) else (
    if /i "%c%==n" goto check
)

:[ Invalid input ]
cls & echo Error: "%c%" is not y/n. & pause & goto :choice

答案 1 :(得分:1)

直接回答你的问题......好吧,我不确定你要求说实话。我在解密时遇到问题"我试图让下面的批处理文件增加计数器%var1,只有当" y"并且无法使语法正确。"

我没有看到任何直接的语法错误,但您的脚本确实存在很多逻辑问题。实际上,%var1% 的值是递增。在echo Var1 incremented: %var1%之后添加set /a var1+=1并自行查看。要修复脚本,您需要解决在什么条件下执行哪些语句。

  1. 使用setlocal。这只是一种很好的做法。使用setlocal可以帮助您避免使用仅与此脚本的运行时相关的变量来污染外部控制台线程。

  2. 不要相信用户总会回答" y"或" n"。如果他们回答" w"会发生什么?在编写脚本时,它将继续执行您可能不想要的部分。我有两个建议。

    一个。不要明确检查" n"的答案。如果它不是" y",则假设它" n"。如果这不合适,那么对于紧接在条件之前的任何标签,都要有一个最终else goto label

    湾或者,请考虑使用set /P,而不是choice。例如:

    choice /c YN /m "Do you want to perform the check? "
    
    if errorlevel 2 (
        rem // user chose "N"
    ) else (
        rem // user chose "Y"
    )
    
  3. 在您的:choice部分代码中,Y和N的答案与N的答案之间有什么区别?如上所述,没有区别。无论哪种方式,脚本都会进入:check。在这里检查你的逻辑。

  4. 请考虑使用exitexit /b,而不是goto :EOF。从cmd提示符运行脚本(而不是双击它)时,应避免退出父线程。

  5. 为了善良,请缩进代码并添加一些换行符!那一大堆左倾的命令没有流动,也没有节奏。阅读和排除故障非常繁琐。

  6. 在:

    @ECHO OFF
    :: ask user 
     :choice
     set /P c=Has the check been done [y/n]
     if /i %c%==y (
     set /P c=Do you want to send the DOSE report[y/n]?
     ) else (
     if /i %c%==n goto check
     )
     :check
     set /P c=Do you want to perform the check [y/n]
     if /i %c%==y (
     set /P c=please complete the check and click enter
     goto file
     ) else (
     if /i %c%==n goto goodbye
     )
    

    它像平板一样,一眼就看不出哪些陈述是祖先,哪些是后代或断裂发生的地方。

    后:

    @ECHO OFF
    setlocal
    
    :choice // ask user
    choice /c YN /m "Has the check been done? "
    if not errorlevel 2 (
        choice /c YN /m "Do you want to send the DOSE report? "
        if errorlevel 2 (
            goto goodbye
        )
    )
    
    :check
    choice /c YN /m "Do you want to perform the check? "
    if errorlevel 2 goto goodbye
    
    set /P "c=Please complete the check and click enter: "
    

    请参阅?这样阅读起来会更愉快。顺便说一下,你可能已经注意到我把'#34;问用户"使用:choice标签发表评论。在定义解释预期参数的函数时,或者只是解释正在进行的操作时,通常会这样做。你真的不需要双斜线。它只是让Stack Overflow的Ted Turner Technicolor解析器证明这是一个评论。