为什么我的 GOTO 语句不起作用(批量)

Why is my GOTO statement not working (batch)

无论输入什么,它总是到达第一翻领

我看到其他帖子也有同样的问题,但他们犯的 none 语法错误出现在我的脚本中。

这是脚本:

@echo off
cls

cd /d %~dp0

echo "Include files? [Y/N]"

set /p option=

if %option%=="Y" GOTO yes
if %option%=="y" GOTO yes
if %option%=="N" GOTO no
if %option%=="n" GOTO no

:yes
cls
powershell -command "iex \"tree /f\" > \"tree-filed.txt\""
GOTO end

:no
cls
powershell -command "iex \"tree\" > \"tree-folders.txt\""
GOTO end

:end
cls
echo the tree list was created.
pause

我错过了什么?

你也必须在 IF 语句中使用括号,如果你没有,它会自动执行 IF 语句下的操作。

@echo off
cls

cd /d %~dp0

echo "Include files? [Y/N]"

set /p option=

if "%option%"=="Y" GOTO yes
if "%option%"=="y" GOTO yes
if "%option%"=="N" GOTO no
if "%option%"=="n" GOTO no

:yes
cls
powershell -command "iex \"tree /f\" > \"tree-filed.txt\""
GOTO end

:no
cls
powershell -command "iex \"tree\" > \"tree-folders.txt\""
GOTO end

:end
cls
echo the tree list was created.
pause

有效,但一些背景信息可能会有所帮助:

  • Squashman所述,一个if条件要么要求双方 要么(双)引号要么不引号;也就是说,if %option%==y ...if "%option%"=="y" ... 都有效:

    • 双引号形式更健壮,它还可以正确处理具有 元字符 的值,例如 &,但就是否存在空格而言,匹配必须 完全

    • 相反,只有 unquoted 形式允许前导和尾随空格;例如如果用户输入 y 而不仅仅是 y.

      if %option%==y ... 仍然有效
  • 您可以使用if/I选项进行比较例如,不区分大小写,这样就无需分别检查yYhelp if 显示更多信息。

  • tree.com 是一个独立的可执行文件,可以从 any 调用(Windows) shell,所以 通常 没有充分理由调用 PowerShell (powershell.exe,这是昂贵的),因为您可以直接从批处理文件调用 tree - 尽管您可能需要 PowerShell 来控制 字符编码 输出文件。[1]

    • 顺便说一句:在 PowerShell 内部 不需要 Invoke-Expression (iex), ;调用外部可执行文件(例如 tree.com 的最佳方法基本上与 cmd.exe 相同(见下文)。

    • 如果您需要PowerShell,按如下方式调用,例如:
      powershell -command "tree > tree-folders.txt"

因此,您的批处理文件的精简版本如下所示(省略cls 命令):

@echo off

cd /d "%~dp0"

:prompt
echo "Include files? [Y/N/Q]"

set /p option=

if /I "%option%"=="y" GOTO yes
if /I "%option%"=="n" GOTO no
if /I "%option%"=="q" GOTO :eof
goto prompt

:yes
tree /f > tree-files.txt
GOTO end

:no
tree > tree-folders.txt
GOTO end

:end
echo the tree list was created.
pause

因为 Stephan points out, the standard choice.exe 实用程序提供了 更简单的提示解决方案:

choice /c ynq /m "Include files?"
if %ERRORLEVEL% EQU 1 goto yes
if %ERRORLEVEL% EQU 2 goto no
goto :eof

choice.exe:

  • 不区分大小写默认(使用/CS区分大小写)

  • 仅接受来自用户的单个输入字符,立即退出提示(没有Enter keypress required), %ERRORLEVEL% 变量设置为字符在传递给 /C[=53 的允许字符列表中基于 1 的位置=]

    • 注意:上面故意使用了,例如if %ERRORLEVEL% EQU 1而不是if ERRORLEVEL 1,因为后者使用了等于或大于逻辑,这将要求您颠倒 分支语句的顺序。
  • 自动验证输入(输入无效字符时发出蜂鸣声)

有关详细信息,请参阅 choice /?


[1] 但是,如果 命令的输出包含 非 ASCII 字符 并且您确实需要 PowerShell希望输出重定向(>)创建 UTF-16LE(“Unicode”)文件(Windows PowerShell)或(无 BOM)UTF-8 文件(PowerShell (Core) v6+)。使用 cmd.exe 中的 > 会生成 OEM 编码的文件,该文件基于通过 chcp 报告的控制台代码页。或者,您可以通过 chcp 65001 将控制台代码页切换为(无 BOM)UTF-8,但这不适用于 tree.com,因为它太旧而无法支持此代码页。相比之下,它可以与 dir 的输出一起使用。