使用 SSH.NET 响应交互式 shell 提示

Respond interactive shell prompts using SSH.NET

我想通过 ASP.NET 应用程序创建一个 SFTP 帐户。为了定义它的密码,我需要输入两次

root@localhost:~# passwd fadwa
Enter new password:
Retype new password:
passwd: password updated successfully 

要通过 C# 代码来实现,我在这里查阅了很多解决方案后尝试了以下方法,但它不起作用。

using (var client = new SshClient("xx.xxx.xxx.xxx", 22, "root", "********"))
{
    client.Connect();
    ShellStream shellStream = client.CreateShellStream(string.Empty, 0, 0, 0, 0, 0);
    StreamWriter stream = new StreamWriter(shellStream);
    StreamReader reader = new StreamReader(shellStream);
    stream.WriteLine("passwd fadwa"); //It displays -1
    stream.WriteLine("fadwa");
    stream.WriteLine("fadwa");
    Console.WriteLine(reader.Read());    // It displays -1     
    client.Disconnect();
}

我什至没有使用 StreamWriter 而是直接尝试过:

shellStream.WriteLine("passwd fadwa\n" + "fadwa\n" + "fadwa\n");
while (true) Console.WriteLine(shellStream.Read()); 

还有

shellStream.WriteLine("passwd fadwa");
shellStream.WriteLine("fadwa");
shellStream.WriteLine("fadwa"); 
while (true) Console.WriteLine(shellStream.Read()); 

我明白了,它卡在那里!!

关于它为什么不起作用或其他解决方案的任何建议?我想我已经尝试过第二种解决方案并且它有效,但现在不行。

您可能需要在出现提示后才发送输入。如果您过早发送输入,它会被忽略。

一个蹩脚的解决方案是这样的:

shellStream.WriteLine("passwd fadwa");
Thread.Sleep(100);
shellStream.WriteLine("fadwa");
Thread.Sleep(100);
shellStream.WriteLine("fadwa"); 

更好的解决方案是等待提示,然后再发送密码 – expect-like:

shellStream.WriteLine("passwd fadwa");
shellStream.Expect("Enter new password:");
shellStream.WriteLine("fadwa");
shellStream.Expect("Retype new password:");
shellStream.WriteLine("fadwa");

一般来说,自动化 shell 总是容易出错,应该避免。