在 shell 脚本中执行的批处理文件不等待用户输入

Batch file executed in shell script not waiting for user input

我偶然发现了 git-hooks,并试图在 Windows 上创建一个 运行。所以我决定使用批处理文件来这样做,因为它看起来很简单。

首先,我将 pre-commit 示例重命名为 pre-commit 并在那里调用了我的 bat 步骤:

#!/bin/sh
$(pwd)/git-hooks/hooks/unit_test.bat &&
$(pwd)/git-hooks/hooks/integration_test.bat

unit_test.bat 仅显示一些消息和 运行s 单元测试任务,但 integration_test.bat 提示用户是否要 运行 这些测试,因为它们通常比较慢。

问题是提示(通过'choice'或'set /p'完成)没有得到用户输入:

我尝试添加 start 来调用 .bat 文件,但它会在另一个 cmd 上打开它们,因此无法停止提交。

引用的文件

我认为 gradlew 实际上是另一个批处理文件,gradlew.bat,所以我假设,如果您希望它在完成后 return 到脚本,您应该使用Call 命令。此外,您应该知道 & 将两个单独的命令连接在一行中,而 && 运行 只有在前一个命令成功时才执行一个命令。在您的情况下,Echo 命令不可能不成功,因此只需要 &。此外,如果错误代码为 1 或更高,If ErrorLevel 1 表示,这意味着在您发布的代码中,代码将始终为 goto sim。您应该改用 If Not ErrorLevel 2If %ErrorLevel% Equ 1If "%ErrorLevel%" == "1".

示例:(请插入 gradlew.bat 的完整路径,而不是依赖容易损坏或受影响的 %Path% 变量,如果包含空格,请将路径和可执行文件名称用双引号引起来或有问题的字符)。我已经删除了下面示例中不必要的连接,因为脚本中不需要它。

unit_test.bat

@Echo Off
Echo ^> Testes unitários
Call gradlew.bat testReport || (Echo(& Echo Testes unitários falharam! Acesse o relatório de testes para conferir.& Exit 1)

integration_test.bat

@Echo Off
Echo(
Echo ^> Testes integrados
%SystemRoot%\System32\choice.exe /C sn /M "Esses testes geralmente são mais lentos. Quer rodar os testes integrados"
If Not ErrorLevel 2 GoTo sim
Echo(
Echo Não se esqueça de confirmar que os testes integrados passam antes de fazer o 'git push'!
Exit /B

:sim
Call gradlew.bat integrationTests || (
    Echo(
    Echo Testes integrados falharam! Acesse o relatório de testes para conferir.
)
Exit 1

或:

@Echo Off
Echo(
Echo ^> Testes integrados
%SystemRoot%\System32\choice.exe /C sn /M "Esses testes geralmente são mais lentos. Quer rodar os testes integrados"
If ErrorLevel 2 GoTo nao
Call gradlew.bat integrationTests || (
    Echo(
    Echo Testes integrados falharam! Acesse o relatório de testes para conferir.
)
Exit 1

:nao
Echo(
Echo Não se esqueça de confirmar que os testes integrados passam antes de fazer o 'git push'!
Exit /B

我还建议,根据您使用的一些字符,确保脚本 运行 使用适当的代码页(可能是 1252)。

冻结错误是由于 git-hooks 禁用了交互性,正如@AnthonySotille 指出的那样。

我通过将提示提取到另一个 .bat 文件并使用 start /wait 调用它们来绕过这种情况。这会打开另一个 cmd,运行提示,然后使用成功代码表示 Y 和失败代码表示 N 退出。这似乎不是一个好的做法,但就目前而言,它完成了工作。

这个问题可能被认为是 How do I prompt the user from within a commit-msg hook?

的重复问题