在 Windows 批处理文件中将输入管道输入到 Plink 会添加额外的换行符

Posted

技术标签:

【中文标题】在 Windows 批处理文件中将输入管道输入到 Plink 会添加额外的换行符【英文标题】:Piping input into Plink in Windows batch file adds extra line feeds 【发布时间】:2022-01-18 00:36:17 【问题描述】:

我正在尝试编写一个批处理文件以在 Windows 10 Pro 中运行,该文件将使用 Plink 建立与远程服务器的 SSH 会话并执行一些命令。一切正常,除了出于某种原因,我在管道中输入的每个ECHO 命令都会有额外的换行符。通常,这不是问题,直到我正在运行的命令需要一些特定的用户反馈,即按下Y 确认操作。由于它在测试STSTest 命令之后和接收Y 字符之前收到了额外的换行符,因此会引发错误。

这是我的批处理脚本:

set PATH=C:\Program Files\PuTTY;%PATH%
set TestNum=%1

(
    TIMEOUT /t 1 > nul
    ECHO cd /usr/bin/core/test
    ECHO rm STS_*.txt
    ECHO rm STS_T1_Test%TestNum%.txt
    ECHO ./STSTest --T 2 --i %TestNum%
    TIMEOUT /t 1 > nul
    ECHO Y
    TIMEOUT /t 1 > nul
    ECHO exit
) | plink -ssh 192.168.1.20 -l root -pw ***

是否有人知道如何消除多余的换行符,以便在输入STSTest 命令后以正确的顺序输入Y


这是一个更简单的示例,展示了我正在战斗的内容。如果我定义这个简单的批处理文件:

(
    TIMEOUT /t 1 > nul
    ECHO cd /
    ECHO cd usr
    ECHO cd bin
    ECHO cd core
    ECHO cd test
    TIMEOUT /t 1 > nul
    ECHO exit
) | plink -ssh 192.168.1.20 -l root -pw ***

命令窗口的结果如下所示:

Last login: Wed Jul 29 23:53:30 2020 from 192.168.1.7
root@core-A:~# cd /
root@core-A:/#
root@core-A:/# cd usr
root@core-A:/usr#
root@core-A:/usr# cd bin
root@core-A:/usr/bin#
root@core-A:/usr/bin# cd core
root@core-A:/usr/bin/core#
root@core-A:/usr/bin/core# cd test
root@core-A:/usr/bin/core/test#
root@core-A:/usr/bin/core/test# exit

在每个ECHO 命令之后我都会得到一个额外的换行符。

【问题讨论】:

【参考方案1】:

批处理文件 echo 使用 Windows 换行符(回车+换行)。

将newline hack 与无行尾hack 结合起来:

@echo off
REM don't remove blank lines below
set NLM=^


set NL=^^^%NLM%%NLM%^%NLM%%NLM%

(
    <nul set /P=foo%NL%
    <nul set /P=foo%NL%bar%NL%
) > test.txt

test.txt 变成(十六进制输出)

66 6F 6F 0A 66 6F 6F 0A 62 61 72 0A     foo.foo.bar.

【讨论】:

感谢您的回复。我试过了,不幸的是,它似乎正在删除所有换行符。会话进入 "./STSTest --T 2 --i %TestNum%" 行,并坐在那里直到 3 秒超时并执行 "ECHO Y" 行,然后添加 "Y" 和一个新行第一行的结尾,我错过了响应窗口。 那么你应该试着更好地解释你需要什么。每个 ECHO 都以换行符结尾,除非您使用 hack... 我用我遇到的问题更新了我的原始帖子。这就像 ECHO 命令每次调用时都会发送两个不同的换行符。 我尝试了一个我之前找到的类似这样的示例,但它不起作用。我想我会通过复制/粘贴您的示例再试一次,并且得到相同的结果。当我尝试使用 %NL% 变量时,命令会话挂起。不过,我想我已经在马丁的帮助下找到了解决办法。感谢您的回复。【参考方案2】:

当您执行plink 而其命令行上没有任何命令时,plink 会启动一个交互式 终端会话。这有很多不需要的副作用。包括你面对的那些。

添加-T switch to plink command line 以避免这种情况:

(
...
) | plink -T -ssh 192.168.1.20 -l root -pw ***

另一种选择是在服务器端执行所有操作并在plink 命令行上指定完整命令(在这种情况下,您还将need to add the -batch switch):

plink -ssh 192.168.1.20 -l root -pw *** -batch "cd /usr/bin/core/test && rm STS_*.txt && rm STS_T1_Test%TestNum%.txt && (echo Y | ./STSTest --T 2 --i %TestNum%)"

或者这两种方法的某种组合。


类似问题:

Windows batch scripting: SSH with Plink showing strange sequences in output Executing command using Plink does not work, but does in PuTTY Script via Plink in .bat behaves differently

【讨论】:

使用第一个选项时,我连接到“-sh: line 1: cd: too many arguments”的设备出现错误。使用第二个选项,批处理文件运行顺利,但我确实必须将 -batch 选项添加到 plink call "plink -ssh -batch 192.168.1.20 -l root -pw"

以上是关于在 Windows 批处理文件中将输入管道输入到 Plink 会添加额外的换行符的主要内容,如果未能解决你的问题,请参考以下文章

将批处理文件输出管道传输到 Python 脚本

在 Vim 中将缓冲区管道传输到外部命令

如何在批处理文件中将输入传递给.exe?

在 Windows 中将进程的输出异步传输到文件

节点流和处理流

标准I/O与管道;用户组和权限;文件处理工具及正则表达式总结