gpt4 book ai didi

java - ssh 与 jsch : non 'simple' command output trailed with unexpected output combined from fragments of the command in use

转载 作者:太空宇宙 更新时间:2023-11-04 05:53:02 28 4
gpt4 key购买 nike

我使用 jcraft.jsch channel 在 ssh 上运行多个命令,我发现每当我使用一些复杂的命令(使用正则表达式或使用管道)时,该命令的输出都会有一个意外的“前缀”,该“前缀”由命令片段组合而成,或者整个命令碎片化为用多个空格分隔的小块,并与各处的“<”字符组合...

示例1:

#ls /opt/qb/data2/oscar/process-manager-helper/*/var/core-dump/{2089,2090,2091,2092,2093,2094,2095}.*

ger-helper/*/var/core-dump/{20

<2/oscar/process-manager-helper/*/var/core-dump/{208 9,2090,2091,2092,ls: cannot access /opt/qb/data2/oscar/process-manager-helper/*/var/core-dump/2090.*: No such file or directory
ls: cannot access /opt/qb/data2/oscar/process-manager-helper/*/var/core-dump/2092.*: No such file or directory
ls: cannot access /opt/qb/data2/oscar/process-manager-helper/*/var/core-dump/2094.*: No such file or directory
ls: cannot access /opt/data2/oscar/process-manager-helper/*/var/core-dump/2095.*: No such file or directory
/opt/qb/data2/oscar/process-manager-helper/0/var/core-dump/2089.20141126-195527.213-00000000-opt.dell.srvadmin.bin.idracadm7.idracadm7.core.gz
/opt/qb/data2/oscar/process-manager-helper/0/var/core-dump/2091.20141126-201557.530-00000000-opt.dell.srvadmin.bin.idracadm7.idracadm7.core.gz
/opt/qb/data2/oscar/process-manager-helper/0/var/core-dump/2093.20141126-202822.524-00000000-opt.dell.srvadmin.bin.idracadm7.idracadm7.core.gz

示例2:

#du -s --block-size=1 /opt/qb/data2/oscar/process-manager-helper/0/var/core-dump/2089.20141126-195527.213-00000000-opt.dell.srvadmin.bin.idracadm7.idracadm7.core.gz | awk { print $1; }

rvadmin.bin.idracad

<-195527.213-00000000-opt.dell.srvadmin.bin.idracadm 7.idracadwk

<ell.srvadmin.bin.idracadm7.idracadm7.core.gz | awk { print $1; }
86016

这是一个重现它的示例代码(至少在我的设置上):

public static void main(String[] args) throws Exception
{
JSch myConnection = new JSch();
myConnection.setKnownHosts("/dev/null");
Session mySession = myConnection.getSession("root", "my-host.my-lab.com", 2222);
mySession.setPassword("password123");
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
mySession.setConfig(config);
mySession.connect(15000);
Channel myChannel = mySession.openChannel("shell");

((ChannelShell) myChannel).setPtyType("exec");
InputStream fromServer = myChannel.getInputStream();
OutputStream toServer = myChannel.getOutputStream();

myChannel.connect();

String commandString = "du -s --block-size=1 /opt/base/dir/eventLog | awk '{ print $1; }'";
toServer.write((commandString + "\n").getBytes());
toServer.flush();

Thread.sleep(5000);

StringBuffer result = new StringBuffer();

while (true)
{
int avail = fromServer.available();
if (avail > 0)
{
while (avail > 0)
{
byte[] buf = new byte[avail];
int bytesRead = 0;
if ((bytesRead = fromServer.read(buf)) < 0)
{
throw new IOException("connection is probably closed (can't read " + avail + " from server) - return value is " + bytesRead);
}
for (int i = 0; i < bytesRead; i++)
{
if (buf[i] >= 127 || buf[i] < 9 || (buf[i] >= 14 && buf[i] <= 31) || buf[i] == 11 || buf[i] == 12 || buf[i] == 8)
{
continue;
}
result.append((char) buf[i]);
}
avail = fromServer.available();
}
if (result.toString().trim().endsWith("#"))
{
System.out.println(result);
break;
}
}
}
}

请指教

最佳答案

Channel myChannel = mySession.openChannel("shell");
((ChannelShell) myChannel).setPtyType("exec");
[...]
String commandString = "du ...";
toServer.write((commandString + "\n").getBytes());

您正在打开一个 shell channel ,该 channel 通常用于交互式 session 。然后,您将命令字符串写入 channel 的输入流,该输入流模拟输入命令的字符。这种运行命令的方式是可行的,但远程系统的行为就像是交互式终端 session 一样。特别是,远程 shell 可能会打印命令提示符,而远程 PTY 可能会回显您的程序正在“键入”的文本。我认为这就是您所发生的情况 - 您正在运行的命令的输出与命令提示符和字符回显混合在一起。

您应该考虑使用 ChannelExec运行远程命令而不是 ChannelShell。使用 ChannelExec,远程系统可以直接调用您的命令(而不是调用 shell 并让您将命令提供给 shell 的输入)。当命令退出时 channel 将关闭,并且您不应该被字符回显或命令提示所困扰。

Jsch 有一个ChannelExec example 。您的代码将如下所示:

ChannelExec chan = mySession.openChannel("exec");
chan.setCommand("du ... | awk ...");
// Set input and output streams
// Request a PTY if you think you need one
chan.connect();

chan.connect() 将打开 channel 并在远程系统上启动命令。远程命令的标准输出可以从getInputStream()返回的输入流中读取,命令的标准错误可以从getErrStream()返回的流中读取。或者你可以用这些流做其他事情;请参阅示例。

关于java - ssh 与 jsch : non 'simple' command output trailed with unexpected output combined from fragments of the command in use,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27168654/

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