【问题标题】:Qprocess messes my linux command up (i think). how to fix? [duplicate]Qprocess 弄乱了我的 linux 命令(我认为)。怎么修? [复制]
【发布时间】:2011-11-27 15:57:04
【问题描述】:

我需要强制我的 c++ QT4 应用程序从 linux 命令读取结果。我正在尝试使用 Qpr​​ocess,但是一旦我的命令变得复杂,它就会以某种方式变得混乱(只是猜测)并且不起作用。

这里我试着为你做一个小例子:

QProcess process;
command = "ls -l | grep a | sort";
qDebug() << "Execute command -> "+command;
process.start( command );
process.waitForFinished(-1);
QString processStdout = process.readAllStandardOutput();
QString processStderr = process.readAllStandardError();
qDebug() << "Std out -> "+processStdout;
qDebug() << "Std err -> "+processStderr;

这将打印:

Execute command -> ls -l | grep a | sort
"Std out -> " 
"Std err -> ls: |: No such file or directory

如果从控制台运行,while 将正确打印文件名。

如果我用更简单的 command = "ls -l"; 替换 comman,它的工作会很顺畅 该错误由操作系统在标准错误中返回。

因此我猜想用于命令的 Qstring 会以某种方式被操纵。知道发生了什么吗?

【问题讨论】:

    标签: c++ linux qt qprocess


    【解决方案1】:

    QProcess 不支持 shell 命令。因此管道符号不会被 shell 解释,而是直接传递给lsls 将其解释为文件名,并抱怨因为显然没有名为 | 的文件。

    您需要通过重定向 QProcess 对象的输入和输出流来手动设置管道。阅读文档以了解如何执行此操作。

    一般应该如何避免shell命令,而依赖Qt的类和函数。当然没有必要调用grepls,因为使用QRegExpQDir 可以更轻松地完成相同的操作。如果您需要执行子流程,请使用::start(const QString&amp;, const QStringList&amp;, OpenMode) 重载并将所有参数作为列表传递以避免引用问题。

    【讨论】:

    • 我不认为这只是|。如果我使用命令 egrep -l 'aaa' /user/*/mydir/* 说 egrep: /user/*/mydir/* 没有这样的文件或目录。在这个命令中我没有|
    • 同样的问题。 * 通配符也由 shell 解释。在 shell 上发生的情况是,通配符被替换,命令被所有匹配的文件调用。如果您使用 QProcess,则不会进行此类替换,并且 grep 被称为 egrep "/user/*/mydir/*" (注意 ",即模式作为参数提供给 egrep)。在 shell 上尝试使用 "你也会遇到同样的问题。
    • 现在我明白了。非常感谢!
    【解决方案2】:

    试试这个:

    从 QProcess 运行 shell 并将参数传递给 shell。示例:

    QStringList options;
    options << "-c" << "ls -l | grep a | sort";
    QProcess process;
    process.start("/bin/sh", options); //Use sh or another shell 
    

    让我知道这是否有效。

    【讨论】:

      【解决方案3】:
      command = "ls -l | grep a | sort";
      

      实际上不是一个进程,而是 3 个不同进程的管道:ls、grep 和 sort。

      【讨论】:

        【解决方案4】:

        感谢大家的帮助。

        为了做我需要做的事,我不得不改变方法:

        std::string cmd("/sbin/ifconfig eth0");
        FILE* pfd = popen(cmd.c_str(), "r");
        
        if (pfd)
        {
          while (!feof(pfd))
          {
            char buf[1024] = {0};
        
            if (fgets(buf, sizeof(buf), pfd) > 0)
            {
              std::cout << "buf = " << buf;    // a newline is already present
            }
          }
          pclose(pfd);
        }
        

        【讨论】:

        • -1。 QProcess 完全可以做到这一点,无需求助于 C 函数。
        • 如果这个答案解决了你的问题,你应该接受它而不是接受另一个。
        猜你喜欢
        • 2016-08-16
        • 2020-05-11
        • 1970-01-01
        • 2013-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-12
        相关资源
        最近更新 更多