【问题标题】:Finding if an SSH connection succeeded查找 SSH 连接是否成功
【发布时间】:2017-11-06 19:46:54
【问题描述】:

我正在尝试让我的程序使用 SSH 连接到另一台计算机。它是通用的(用户将提供主机名、IP 和密码),因此不能使用密钥。这是我到目前为止的代码:

func terminalSSH(host:String, password:String, IP:String) {
    let pipe = Pipe()
    let args = ["-p", password, "ssh", "\(host)@\(IP)"]
    let task = Process()
    task.launchPath = "/usr/local/bin/sshpass"
    task.arguments = args
    task.standardOutput = pipe

    task.launch()

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)

    print(output)


}

我的问题是我看不到使用 sshpass 连接是否成功。我希望在连接成功或失败时通知用户。此外,似乎 sshpass 是我可以用于 SSH 的唯一命令,因为终端强制用户输入密码。我知道这段代码可以建立连接,因为我的测试目标计算机上的 system.log 会显示它。谢谢。

【问题讨论】:

    标签: swift macos shell ssh swift3


    【解决方案1】:

    首先,您不应该使用 sshpass 和纯文本密码,而是使用私钥。

    要获取任务退出代码,您可以使用以下代码:

    task.waitUntilExit()
    let status = task.terminationStatus
    

    但请注意,waitUntilExit 将阻止此方法的返回,直到会话结束。

    无论会话在 10 分钟后结束,还是由于错误而立即结束,您都可以评估 terminationStatus 以查看程序是如何退出的。

    如果返回码是0,一切顺利退出;如果有一个非零值,您可以根据失败的原因采取不同的操作。

    task.waitUntilExit()
    
    let status = task.terminationStatus
    if status == 0 {
    
        print("Graceful exit.")
    } else {
    
        print("Failed with code " + status)
    }
    

    在这里检测和响应成功的连接会更加困难,因为只要 ssh 会话打开,waitUntilExit 调用就可能会阻塞。

    您还可以选择使用循环并检查task.isRunning

    【讨论】:

    • 有没有其他方法可以在不等待终止的情况下立即找到状态?
    • 对不起,我根本不使用 Swift,所以我不能在这里给出一个可靠的答案。您可以轮询isRunning 几秒钟以查看连接是否失败,但任何等待都会阻塞上游调用,除非您进行一些线程管理。
    猜你喜欢
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    相关资源
    最近更新 更多