Plink 在登录前发送命令

Plink sends commands before login

我正在使用 Plink 将 ssh 与 C# 连接。但是当我向服务器发送命令时,Plink 在登录之前发送命令。因此有些命令不起作用。

我从外面发送命令,这些代码是,

cd /ssh/fd/
./myscript.sh

您可以在下面找到示例代码;

void connect()
{
     ProcessStartInfo psi = new ProcessStartInfo()
     {
         FileName = Application.StartupPath + @"\_Components\plink.exe",
         Arguments = String.Format("-ssh -hostkey {3} {0}@{1} -pw {2}", Users, Host, Password, Hostkey),
         RedirectStandardError = true,
         RedirectStandardOutput = true,
         RedirectStandardInput = true,
         UseShellExecute = false,
         CreateNoWindow = true
     };

     Process p = Process.Start(psi);
     m_objLock = new Object();
     m_blnDoRead = true;
     AsyncReadFeedback(p.StandardOutput);
     AsyncReadFeedback(p.StandardError);
     StreamWriter strw = p.StandardInput;
     string[] lstCommands = commandList.ToArray();

     foreach (string cmd in lstCommands)
     {
         strw.WriteLine(cmd);
     }

     strw.WriteLine("exit");
     p.WaitForExit();

     return m_szFeedback;
}

private String m_szFeedback;
private Object m_objLock;
private Boolean m_blnDoRead;

public void AsyncReadFeedback(StreamReader strr)
{
    Thread trdr = new Thread(new ParameterizedThreadStart(__ctReadFeedback));
    trdr.Start(strr);
}

private void __ctReadFeedback(Object objStreamReader)
{
    StreamReader strr = (StreamReader)objStreamReader;
    string line;
    while (!strr.EndOfStream && m_blnDoRead)
    {
        line = strr.ReadLine();
        lock (m_objLock) { m_szFeedback += line + "\r\n"; }
    }
}

这是输出:

Feedback from: xxx.xx.xxx.xx
cd /ssh/fd/

Last successful login:       Thu Nov 19 12:45:42 EET 2015 xxxxxxxxxxxxx  
Last authentication failure: Fri Dec 18 19:40:55 EET 2015 xxxxxxxxxxxxxxx
Last login: Thu Nov 19 12:45:42 2015 from xxxxxxxxxxx

(c)Copyright 1983-2006 Hewlett-Packard Development Company, L.P.
(c)Copyright 1979, 1980, 1983, 1985-1993 The Regents of the Univ. of California
(c)Copyright 1980, 1984, 1986 Novell, Inc.
(c)Copyright 1986-2000 Sun Microsystems, Inc.
(c)Copyright 1985, 1986, 1988 Massachusetts Institute of Technology
(c)Copyright 1989-1993  The Open Software Foundation, Inc.
(c)Copyright 1990 Motorola, Inc.
(c)Copyright 1990, 1991, 1992 Cornell University
(c)Copyright 1989-1991 The University of Maryland
(c)Copyright 1988 Carnegie Mellon University
(c)Copyright 1991-2006 Mentat Inc.
(c)Copyright 1996 Morning Star Technologies, Inc.
(c)Copyright 1996 Progressive Systems, Inc.

Confidential computer software. Valid license from HP required for
possession, use or copying.  Consistent with FAR 12.211 and 12.212,
Commercial Computer Software, Computer Software Documentation, and
Technical Data for Commercial Items are licensed to the U.S. Government
under vendor's standard commercial license.

You have mail.
./myscript.sh

exit

LANG has been set to C, but you can choose from C or ja_JP.SJIS or ja_JP.eucJP or ja_JP.utf8

hknnzb11:/home/def : ./myscript
-bash: ./myscript.sh: No such file or directory
hknnzb11:/home/def : 
hknnzb11:/home/def : exit
logout
logout
Using username "def".

我认为是同步问题,但我不知道如何解决。

你可以找到我试过的 SSH.NET 例子。

using (var client = new SshClient(Host, Users, Password))
{
    client.Connect();
    var cmd = client.RunCommand("cd /ssh/fd/ ; ./myscript.sh");
    MessageBox.Show(cmd.Result);
    client.Disconnect();
}

谢谢。

与其说是代码问题,不如说是 SSH 服务器问题。

无论如何,您最好使用-m command-line switch 向Plink 提供命令脚本。不同之处在于,-m 指定的命令在 "exec" 通道中以更受控的方式执行,然后在重定向输入时在您正在使用的 "shell" 通道中执行。


更好的是,使用本机 C# 库来执行 "exec" 频道中的命令:

例如使用 SSH.NET:

using (var client = new SshClient(Host, Users, Password))
{
    client.Connect();
    client.RunCommand("cd /ssh/fd/ ; ./myscript.sh");
    client.Disconnect();
}

来源:C# send a simple SSH command


如果上述方法不起作用,那是 SSH 服务器中的错误。

您所能做的就是在发送命令之前等待几秒钟。为此,您需要像在原始代码中一样继续使用 "shell" 频道。

在"exec"频道(我的解决方案)中,您不能延迟命令。服务器本身应该只在会话完全初始化后才执行命令。