用 QProcess 包装 SFTP

Posted

技术标签:

【中文标题】用 QProcess 包装 SFTP【英文标题】:Wrap SFTP with QProcess 【发布时间】:2019-08-01 11:35:29 【问题描述】:

我想在我的代码中尝试使用 QProcess 在 linux 系统上启动 sftp:

    QProcess* pProc = new QProcess(this);
    QString strHost = clsMainWnd::strGetHostName()
           ,strPort = clsMainWnd::strGetPort()
           ,strUsername = clsMainWnd::strGetUsername();
    QStringList slstCmdArgs;
    slstCmdArgs << (strUsername + QString("@") + strHost)
                << (QString("-P") + strPort);
    pProc->start("sftp", slstCmdArgs);
    while( pProc->waitForStarted() != true ) 
    
    QByteArray bytaryIn = pProc->readAllStandardOutput();
    qDebug() << bytaryIn;

我要做的是等待“密码:”提示然后注入密码,但 bytaryIn 始终为空。

我已验证命令行参数的格式正确并输出到控制台。

然后我在终端中使用它们进行测试,它们按预期工作。

命令将被格式化为:

    sftp User@HostName -P22

[编辑] 我已将此代码重写为以下内容:

    QString strHost = clsMainWnd::strGetHostName()
           ,strPort = clsMainWnd::strGetPort()
           ,strUsername = clsMainWnd::strGetUsername();
    QStringList slstCmdArgs;
    slstCmdArgs << (strUsername + QString("@") + strHost)
                << (QString("-P") + strPort);
    mpSFTP = new QProcess(this);
    connect(mpSFTP, SIGNAL(readyReadStandardOutput())
           ,this, SLOT(readSFTPoutput()));
    mpSFTP->start("sftp", slstCmdArgs);

我在插槽中有一个调试语句,但我从来没有看到它,所以没有发出信号。

【问题讨论】:

【参考方案1】:

快速测试显示sftp直接访问终端询问密码。您必须使用为您输入密码的wrapper script。

另一种方法是创建一个伪 tty 对并使用它来输入密码,但您将无法使用任何 QProcess 机制。

【讨论】:

我正在编写的代码背后的想法是通过执行与链接中的脚本相同的操作来自动登录,但使用 QProcess 并管理数据而不是使用期望。 那么你需要说服QProcess在一个伪tty中运行sftp,根据API这是不可能的。如果您的应用程序与 GPL 兼容,请查看 KPty。 或者,直接使用libssh2 并跳过所有人机界面的东西。 我会这样做,但由于问题,这就是我走这条路的原因。 就像KPtyProcess 所做的那样:子类QProcess。在初始化时,使用openpty 构造一个 pty。然后覆盖setupChildProcess 并使用从文件描述符调用login_tty。最后将您的QProcess 与主文件描述符相关联。如果这听起来太多,请注意 KPty 显然是 LGPL,所以我认为您可以将其用作动态库,即使在商业产品中也是如此。

以上是关于用 QProcess 包装 SFTP的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 QProcess 运行 vim 终端

QProcess的正确用法

QT Creator QProcess

QT中QProcess调用详解及实验

QT中QProcess调用命令行的痛苦经历

QT调用外部程序