在Qt控制台应用程序中读取和写入QProcess

注意:这似乎是一个具体的问题,但希望它可以编辑为所有相关

我需要与QProcess对象进行交互。

问题:

在调用QProcess:write(input)之后,我没有从QProcess获得任何输出QProcess:write(input)

更多信息:

阅读文档页面让我在下面创建一个示例:

我有一个请求用户输入的脚本,最后根据用户输入显示和适当的消息。

测试:

将“日志”功能添加到我的脚本进行测试后,会发生以下情况:

  • 脚本执行
  • 脚本请求用户输入(由'第一'确认qDebug() << p->readAll()
  • 脚本接受来自QProcess输入(由脚本'日志输出'确认)
  • 在此之后,没有收到任何输出。 以下两条调试语句都会触发(即每个都等待30秒)

    if (!p->waitForReadyRead()) {
        qDebug() << "waitForReadyRead() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
    }
    if (!p->waitForFinished()) {
        qDebug() << "waitForFinished() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
    }
    

    其次是:

    QString s = QString(p->readAll() + p->readAllStandardOutput());
    

    其中s是一个空字符串。

    问题是s应包含“成功”或“失败”

    调用代码:

    QString cmd = QString("sh -c "/path/to/bashscript.sh"");
    QString input = QString("Name");
    QString result = runCommand(cmd, input)
    

    流程代码:

    //takes 2 parameters, 
    //    cmd which is the code to be executed by the shell
    //    input which acts as the user input
    
    QString runCommand(QString cmd, QString input){
        QProcess *p = new QProcess(new QObject());
        p->setProcessChannelMode(QProcess::MergedChannels);   //no actual reason to do this
        p->start(cmd);
        if (p->waitForStarted()) {
            if (!p->waitForReadyRead()) {
                qDebug() << "waitForReadyRead() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
            }
            if (!p->waitForFinished()) {
    
                //reads current stdout, this will show the input request from the bash script
                //e.g. please enter your name:
                qDebug() << p->readAll();  
    
                //here I write the input (the name) to the process, which is received by the script
                p->write(ps.toLatin1());
    
                //the script should then display a message i.e. ("success" o "failed")
                if (!p->waitForReadyRead()) {
                    qDebug() << "waitForReadyRead() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
                }
                if (!p->waitForFinished()) {
                    qDebug() << "waitForFinished() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
                }
            }
            QString s = QString(p->readAll() + p->readAllStandardOutput());
            return s;
        }
        else{
            qDebug() << "waitForStarted() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
        }
        p->waitForFinished();
        p->kill();
        return QString();
    }
    

    script.sh-rwxrwxr-x

    #!/bin/bash
    #returns 
    #    "success" on non empty $n value
    #    "failed: on empty $n value
    #
    echo "enter your name:"
    read n
    if [[ ! -z $n ]];
    then
            echo "success"
            exit 0;
    else
            echo "failed"
            exit 1;
    fi
    

    UPDATE

    @KevinKrammer我修改了运行命令,就像你说的,同样使用QStringList和args。

    仍然没有得到输出,事实上waitForReadyRead()waitForFinished()立即returns false

    呼叫:

    QString r = runCommand(QString("text"));
    

    流程代码:

    QString runCommand(QString input){      
    
        QProcess *p = new QProcess(new QObject());    
        p->setProcessChannelMode(QProcess::MergedChannels);
    
        //script is the same script refered to earlier, and the `cd /home/dev` IS required
        p->start("sh", QStringList() << "-c" << "cd /home/dev" << "./script");
        ;
        if (p->waitForStarted()) {
            if (!p->waitForReadyRead(5000)) {
                qDebug() << "waitForReadyRead() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
            }
            qDebug() << p->readAll();
            p->write(input.toLatin1());
            if(!p->waitForFinished(5000)){
                qDebug() << "waitForFinished() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
            }
            QString s = QString(p->readAll() + p->readAllStandardOutput());
            return s;
        }
        else{
            qDebug() << "waitForStarted() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
        }
        p->waitForFinished();
        p->kill();
        return QString();
    }
    

    流程的终端输出:

    started
    readChannelFinished
    exit code =  "0"
    waitForReadyRead() [false] : CODE:  "5"  | ERROR STRING:  "Unknown error"
    ""
    waitForFinished() [false] : CODE:  "5"  | ERROR STRING:  "Unknown error"
    Press <RETURN> to close this window...
    

    对此有何想法?

    更新2

    @塔罗德感谢您花时间制定解决方案。

    它工作,但不完全是预期的。

    我完全抄袭了你的代码。

    mReadyReadStandardOutput()做了一些更改

    请参阅以下其他信息。

    问题:

    运行应用程序(和脚本)后,我得到一个结果 - >真棒

    每次它是不正确的结果,即“失败”。 - >不是真的

    终端输出:

    void MyProcess::myReadyRead()
    void MyProcess::myReadyReadStandardOutput()
    "enter your name:n"
    ""
    void MyProcess::myReadyRead()
    void MyProcess::myReadyReadStandardOutput()
    "failedn"
    Press <RETURN> to close this window...
    

    脚本内容:

    #!/bin/bash
    echo "enter your name:"
    read n
    echo $n > "/tmp/log_test.txt"
    if [[ ! -z "$n" ]];
    then
            echo "success"
            exit 0;
    else
            echo "failed"
            exit 1;
    fi
    

    /tmp/log_test.txt输出

    myname
    

    从控制台手动运行此操作:

    dev@dev-W55xEU:~$ ls -la script 
    -rwxrwxr-x 1 dev dev 155 Jan 25 14:53 script*
    
    dev@dev-W55xEU:~$ ./script 
    enter your name:
    TEST_NAME
    success
    
    dev@dev-W55xEU:~$ cat /tmp/log_test.txt 
    TEST_NAME
    

    完整代码:

    #include <QCoreApplication>
    #include <QProcess>
    #include <QDebug>
    
    class MyProcess : public QProcess
    {
        Q_OBJECT
    
    public:
        MyProcess(QObject *parent = 0);
        ~MyProcess() {}
    
    public slots:
        void myReadyRead();
        void myReadyReadStandardOutput();
    };
    
    MyProcess::MyProcess(QObject *parent)
    {
        connect(this,SIGNAL(readyRead()),
                this,SLOT(myReadyRead()));
        connect(this,SIGNAL(readyReadStandardOutput()),
                this,SLOT(myReadyReadStandardOutput()));
    }
    
    void MyProcess::myReadyRead() {
        qDebug() << Q_FUNC_INFO;
    }
    
    void MyProcess::myReadyReadStandardOutput() {
        qDebug() << Q_FUNC_INFO;
        // Note we need to add n (it's like pressing enter key)
        QString s = this->readAllStandardOutput();
        qDebug() << s;
        if (s.contains("enter your name")) {
            this->write(QString("myname" + QString("n")).toLatin1());
            qDebug() << this->readAllStandardOutput();
        }
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        MyProcess *myProcess = new MyProcess();
    
        QString program = "/home/dev/script";
    
        myProcess->start("/bin/sh", QStringList() << program);
    
        a.exec();
    }
    
    #include "main.moc"
    

    脚本问题? QProcess问题?


    不幸的是我没有你所有的代码,所以我举了一个例子。 我希望它能帮助你。

    如果我将自己的代码与您的代码进行比较,我认为问题可能在于您没有在写入之后调用readAllStandardOutput() ,也可能没有在main.cpp中调用exec()

    #include <QCoreApplication>
    #include <QProcess>
    #include <QDebug>
    
    class MyProcess : public QProcess
    {
        Q_OBJECT
    
    public:
        MyProcess(QObject *parent = 0);
        ~MyProcess() {}
    
    public slots:
        void myReadyRead();
        void myReadyReadStandardOutput();
    };
    
    MyProcess::MyProcess(QObject *parent)
    {
        connect(this,SIGNAL(readyRead()),
                this,SLOT(myReadyRead()));
        connect(this,SIGNAL(readyReadStandardOutput()),
                this,SLOT(myReadyReadStandardOutput()));
    }
    
    void MyProcess::myReadyRead() {
        qDebug() << Q_FUNC_INFO;
    }
    
    void MyProcess::myReadyReadStandardOutput() {
        qDebug() << Q_FUNC_INFO;
        // Note we need to add n (it's like pressing enter key)
        this->write(QString("myname" + QString("n")).toLatin1());
        // Next line no required
        // qDebug() << this->readAll();
        qDebug() << this->readAllStandardOutput();
    
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        MyProcess *myProcess = new MyProcess();
    
        QString program = "/home/fran/code/myscript.sh";
    
        myProcess->start("/bin/sh", QStringList() << program);
    
        a.exec();
    }
    
    #include "main.moc"
    

    测试应用程序的脚本:

    echo "enter your name:"
    read n
    if [ ! -z "$n" ];
    then
        echo "success"
        exit 0;
    else
        echo "failed"
        exit 1;
    fi
    
    链接地址: http://www.djcxy.com/p/97047.html

    上一篇: reading and writing to QProcess in Qt Console Application

    下一篇: An issue with double brackets in shell scripting