qt执行shell语言java,在Qt控制台应用程序中读写QProcess

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

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

The Problem:

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

More Info:

通过doc pages让我创建了一个示例如下:

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

Testing:

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

脚本执行

脚本请求用户输入(由'first' qDebug() << p->readAll() 确认)

脚本接受来自 QProcess 的输入(由脚本'log output'确认)

在此之后,没有收到输出 . 以下两个调试语句都会触发(即每个等待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 应包含"success"或"failed"

Calling Code:

QString cmd = QString("sh -c \"/path/to/bashscript.sh\"");

QString input = QString("Name");

QString result = runCommand(cmd, input)

Process Code:

//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我按照你的说法修改了run命令,也使用带有args的QStringList .

仍然没有得到输出,实际上是 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 to close this window...

对此的想法?

UPDATE 2

@Tarod感谢您抽出宝贵时间来解决问题 .

它起作用,但并不完全是预期的 .

我完全复制了你的代码 .

mReadyReadStandardOutput() 做了一些改动

请参阅下面的其他信息

The problem:

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

每次都是错误的结果,即“失败” . - >不太棒

Terminal Output:

void MyProcess::myReadyRead()

void MyProcess::myReadyReadStandardOutput()

"enter your name:\n"

""

void MyProcess::myReadyRead()

void MyProcess::myReadyReadStandardOutput()

"failed\n"

Press to close this window...

script contents:

#!/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 output

myname

running this manually from console:

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

#include

#include

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问题?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值