gpt4 book ai didi

batch-file - 为什么管道到标准输入会创建一个无限循环?

转载 作者:行者123 更新时间:2023-12-04 00:46:31 24 4
gpt4 key购买 nike

我目前正在试验管道。所以我创建了一个简单的批处理文件(dos/windows)如下:

@echo off
echo [+] starting batch file
:start
set /p msg="[+] enter msg: "
echo [+] Your message: %msg%
IF "%msg%"=="x" (
echo [x] end loop
goto exit
) ELSE (
goto start
)

:exit
echo [+] bye

只要我从命令行调用它就可以正常工作:
> showAll.bat

S:\80_personalFolder\81_lab\python\ghoul>showAll.bat
[+] starting batch file
[+] enter msg: hello
[+] Your message: hello
[+] enter msg: x
[+] Your message: x
[x] end loop
[+] bye

S:\80_personalFolder\81_lab\python\ghoul>

但是一旦我尝试通过管道将输入传递给它,它就会无限循环运行:
> echo hello | showAll.bat

将导致:
[...]
[+] enter msg: [+] Your message: hello
[+] enter msg: [+] Your message: hello
[+] enter msg: [+] Your message: hello
[+] enter msg: [+] Your message: hello
[+] enter msg: [+] Your message: hello
[...]

我不明白这种行为。有人可以解释我监督的内容或我缺少的内容!我将如何解决这个问题,这样它就不会无限期地运行,但会在循环中的下一个提示下停止,所以我可以手动退出?

更新!首先非常感谢我收到的非常好的答案。它帮助我更好地理解发生了什么。所以我修改了代码以在再次调用 read 之前重置输入变量。
我想实现以下目标:
1) 将“echo hello”管道传输到批处理脚本
2) 一旦脚本从管道输入运行 hello 并重新进入循环......
3) ...我希望能够手动输入其他内容。相反,它仍然会使用脚本将变量设置为的任何默认值无限循环。如何停止管道并切换回默认标准输入?我想这就是我正在努力解决的真正问题。我什至不确定这是否可以完成。

感谢和最好的

最佳答案

set /p var=命令旨在检索要存储到指定变量中的输入数据。行为是

  • 如果有数据要读取,则检索数据并将其存储到指示的变量
  • 中。
  • 如果没有要读取的数据(没有数据或已读取所有数据),则set /p失败(没有错误)和 变量没有改变 .

  • 第二种情况是您所看到的行为的来源。
  • “hello”(来自 echo 命令)在第一次迭代中读取
  • 在第二次迭代中,没有任何数据要读取,但变量没有改变。

  • 您的代码(仅检查变量内容)看不到两种情况之间的区别,因为变量仍然保存来自上一次迭代的数据。

    如果不读取任何数据是循环退出的有效情况,您可以执行以下操作

    :start
    set "msg="
    set /p msg="[+] enter msg: "
    if not defined msg goto :exit

    在每次读取之前重置变量,如果没有读取数据则离开。

    这也可以用更简单的方式写成

    :start
    set /p msg="[+] enter msg: " || goto :exit

    这使用条件运算符 || (如果前一个命令失败,则执行下一个命令)如果 set /p 退出循环失败的。

    已编辑 适应评论:

    所需的行为是从命令中存在的管道中读取数据,但是当数据被读取时, set /p应该从用户那里检索数据。首先我们需要看看管道是如何工作的。

    cmd处理管道操作符,创建了两个新的独立进程来处理管道的左侧和右侧。

    此时,我们有三个 cmd实例(OP问题中的情况):
  • cmd1 : 连接到运行输入命令的控制台
  • cmd2 : 在管道左侧运行命令
  • cmd3 : 运行管道右侧的批处理文件

  • 与每个实例关联的输入/输出流( stdin 是输入流, stdout 是输出流)是:
  • cmd1 :stdin是当前控制台 stdin , stdout是当前控制台 stdout
  • cmd2 : 继承控制台 stdin来自 cmd1 , stdout附在 stdin流在 cmd3
  • cmd3 :stdin附在 stdoutcmd2 , stdout继承自 cmd1

  • 在这种情况下 cmd3正在处理的批处理文件无法到达控制台 stdin流活跃于 cmd1cmd2 .

    所以,在这一点上,我看不到实现指示行为的方法。

    关于batch-file - 为什么管道到标准输入会创建一个无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48524802/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com