问题描述
注意:这似乎是一个特定的问题,但希望可以对其进行所有与之相关的编辑
我需要进行互动
问题:
我什么也没得到 QProcess
在调用 QProcess之后的输出:write(input)
更多信息:
通过导致我在下面创建了一个示例:
我有一个脚本,要求用户输入并最终显示
测试:
添加后我的脚本的日志功能进行测试,会发生以下情况:
- 脚本执行
- 脚本请求用户输入(由'first'
qDebug()<< p-> readAll()
确认) - 剧本接受来自
QProcess
的输入(由脚本 log output确认)
之后这,没有收到输出。以下两个调试语句均会触发(即等待30秒)
if(!p-> waitForReadyRead()){
qDebug()<< waitForReadyRead()[false]:代码:<< QVariant(p-> error())。toString()<< |错误字符串:<< p-> errorString();
}
if(!p-> waitForFinished()){
qDebug()<< waitForFinished()[false]:代码:<< QVariant(p-> error())。toString()<< |错误字符串:<< p-> errorString();
}
接着:
QString s = QString(p-> readAll()+ p-> readAllStandardOutput());
其中 s
是一个空字符串。 / p>
问题是 s
应包含成功或失败
呼叫代码:
QString cmd = QString( sh -c \ /path/to/bashscript.sh\);
QString输入= QString(名称);
QString结果= runCommand(cmd,输入)
过程代码:
//接受2个参数,
// cmd,这是外壳程序要执行的代码
//作为用户输入的输入
QString runCommand(QString cmd,QString input){
QProcess * p = new QProcess(new QObject());
p-> setProcessChannelMode(QProcess :: MergedChannels); //没有实际理由这样做
p-> start(cmd);
if(p-> waitForStarted()){
if(!p-> waitForReadyRead()){
qDebug()<< waitForReadyRead()[false]:代码:<< QVariant(p-> error())。toString()<< |错误字符串:<< p-> errorString();
}
if(!p-> waitForFinished()){
//读取当前标准输出,这将显示来自bash脚本
的输入请求/例如请输入您的姓名:
qDebug()<< p-> readAll();
//在这里,我将输入(名称)写入进程,由脚本
p-> write(ps.toLatin1())接收。
//脚本随后应显示一条消息,即( success o failed)
if(!p-> waitForReadyRead()){
qDebug() << waitForReadyRead()[false]:代码:<< QVariant(p-> error())。toString()<< |错误字符串:<< p-> errorString();
}
if(!p-> waitForFinished()){
qDebug()<< waitForFinished()[false]:代码:<< QVariant(p-> error())。toString()<< |错误字符串:<< p-> errorString();
}
}
QString s = QString(p-> readAll()+ p-> readAllStandardOutput());
return s;
}
else {
qDebug()<< waitForStarted()[false]:代码:<< QVariant(p-> error())。toString()<< |错误字符串:<< p-> errorString();
}
p-> waitForFinished();
p-> kill();
return QString();
}
script.sh ( -rwxrwxr-x
)
#!/ bin / bash
#返回
#成功在非空$ n值
#失败:在空$ n值
#
echo输入您的名字:
读n
if [[!!z $ n]];
然后
echo success
exit 0;
else
echo failed
出口1;
fi
更新
@KevinKrammer我也按照您所说的那样修改了运行命令,还使用了带有args的QStringList。
仍然没有得到输出,实际上 waitForReadyRead()
和 waitForFinished()
返回false
调用如下:
QString r = runCommand(QString (文字));
处理代码:
QString runCommand(QString输入){
QProcess * p =新的QProcess(new QObject());
p-> setProcessChannelMode(QProcess :: MergedChannels);
//脚本与前面提到的脚本相同,并且需要使用cd / home / dev`
p-> start( sh,QStringList()<< ; -c<< cd / home / dev<< ./script);
;
if(p-> waitForStarted()){
if(!p-> waitForReadyRead(5000)){
qDebug()<< waitForReadyRead()[false]:代码:<< QVariant(p-> error())。toString()<< |错误字符串:<< p-> errorString();
}
qDebug()<< p-> readAll();
p-> write(input.toLatin1());
if(!p-> waitForFinished(5000)){
qDebug()<< waitForFinished()[false]:代码:<< QVariant(p-> error())。toString()<< |错误字符串:<< p-> errorString();
}
QString s = QString(p-> readAll()+ p-> readAllStandardOutput());
return s;
}
else {
qDebug()<< waitForStarted()[false]:代码:<< QVariant(p-> error())。toString()<< |错误字符串:<< p-> errorString();
}
p-> waitForFinished();
p-> kill();
return QString();
}
过程的最终输出:
已开始
readChannelFinished
退出代码= 0
waitForReadyRead()[false]:代码: 5 |错误字符串:未知错误
waitForFinished()[false]:代码: 5 |错误字符串:未知错误
按< RETURN>关闭此窗口...
对此有何看法?
更新2
@Tarod感谢您抽出宝贵时间提出解决方案。
它可以工作,但是不能完全预期。
我完全复制了您的代码。
对 mReadyReadStandardOutput()
进行了一些更改。
问题:
运行应用程序(和脚本)后,我得到一个结果- >很棒
每次都是不正确的结果,即失败。 ->很棒
终端输出:
void MyProcess :: myReadyRead()
void MyProcess :: myReadyReadStandardOutput()
输入您的名称:\n
void MyProcess :: myReadyRead( )
void MyProcess :: myReadyReadStandardOutput()
failed\n
按< RETURN>关闭此窗口...
脚本内容:
#!/ bin / bash
echo输入您的名字:
读n
echo $ n > /tmp/log_test.txt
如果[[! -z $ n]];
然后
echo success
exit 0;
else
echo failed
exit 1;
fi
/tmp/log_test.txt
输出
我的名字
从控制台手动运行此操作:
dev @ dev-W55xEU:〜$ ls -la脚本
-rwxrwxr-x 1 dev dev 155 Jan 25 14:53脚本*
dev @ dev-W55xEU:〜$。 / script
输入您的名称:
TEST_NAME
成功
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(){}
公用插槽:
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;
//注意,我们需要添加\n(就像按回车键一样)
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程序= / home / dev / script;
myProcess-> start( / bin / sh,QStringList()<<程序);
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(){}
公用插槽:
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;
//注意,我们需要添加\n(就像按回车键一样)
this-> write(QString( myname + QString( \n))。toLatin1() );
//不需要下一行
// qDebug()<< this-> readAll();
qDebug()<< this-> readAllStandardOutput();
}
int main(int argc,char * argv [])
{
QCoreApplication a(argc,argv);
MyProcess * myProcess = new MyProcess();
QString程序= /home/fran/code/myscript.sh;
myProcess-> start( / bin / sh,QStringList()<<程序);
a.exec();
}
#include main.moc
脚本测试应用程序:
回显输入您的名字:
读n
如果[! -z $ n];
然后
echo success
exit 0;
else
echo failed
exit 1;
fi
Noted: this appears to be a specific issue question but hopefully it can be edited for all to related to
I need to interact with a QProcess object.
The Problem:
I am not getting any output from QProcess
after calling QProcess:write(input)
More Info:
Going through the doc pages led me to create an example below:
I have a script requesting user input, and finally displaying and appropriate message based on the user input.
Testing:
After adding a "log" feature to my script for testing, the following occurs:
- script executes
- script requests user input (confirmed by the 'first'
qDebug() << p->readAll()
) - script accepts input from
QProcess
(confirmed by script 'log output')
After this, no output is received. The following 2 debug statements both fire (i.e. wait 30s each)
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();
}
Followed by:
QString s = QString(p->readAll() + p->readAllStandardOutput());
where s
is an empty string.
The issue is s
should contain either "success" or "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 I modified the run command as you said, also using the QStringList with the args.
Still does not get output, infact the waitForReadyRead()
and waitForFinished()
returns false
instantly.
Called with:
QString r = runCommand(QString("text"));
Process Code:
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();
}
Terminal Output of the Process:
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...
Thoughts on this?
UPDATE 2
@Tarod Thank you for taking the time to make a solution.
It works, however not completely is expected.
I copied over your code, exactly.
Made a few changes in the mReadyReadStandardOutput()
See additional info below.
The problem:
After running the application (and script), I get a result -> AWESOME
Everytime it is the incorrect result i.e. "failed". -> NOT AWESOME
Terminal Output:
void MyProcess::myReadyRead()
void MyProcess::myReadyReadStandardOutput()
"enter your name:\n"
""
void MyProcess::myReadyRead()
void MyProcess::myReadyReadStandardOutput()
"failed\n"
Press <RETURN> 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
Full code:
#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"
script issue? QProcess issue?
Unfortunately I don't have all your code, so I made an example. I hope it helps you.
If I compare my code to yours, I think the problem could be you are not calling readAllStandardOutput()
after writing or maybe you are not calling exec()
in your main.cpp.
#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"
Script to test the application:
echo "enter your name:"
read n
if [ ! -z "$n" ];
then
echo "success"
exit 0;
else
echo "failed"
exit 1;
fi
这篇关于在Qt Console应用程序中读写QProcess的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!