QProcess not sending information back after it completes
-
Hi,
Check in the terminal that your line is correct. There is at least the single quotes that are wrong (i.e. they are not single quotes but apostrophes).
-
QString prog = "/bin/bash"; QStringList arguments; arguments <<"-c" << "ifconfig en1 | grep 'inet ' | awk '{print $2}' | sed 's/addr://'"; QProcess proc; proc.start(prog , arguments); proc.waitForFinished(); qDebug() << proc.readAllStandardError() << proc.readAllStandardOutput();
Works fine on OS X.
Note that I don't allocate it on the heap, there's no need in this case. Also with your current code you have a memory leak since you don't delete your QProcess.
-
Hi , I have actually been testing out the QProcess with a couple of
terminal programs now and am finding that I am not reading anything in from
Stdout at all. I have send back some modified code. I changed it to test some
other commands that have output to the terminal window .( The sudo -i
command gives superuser level access from that point onward. )
I am running a debian variant of Linux on this system.QString prog;
QStringList arguments;
QProcess proc;
QString tmp;
int exitStatus;
prog="sudo ";
arguments <<"-i";
proc.start(prog , arguments);
proc.waitForFinished();
tmp = proc.readAllStandardError() + proc.readAllStandardOutput();
exitStatus= proc.exitCode();
ui->textEdit->append(tmp +QString::number(exitStatus));
prog="sudo ";
arguments <<"blkid";
proc.start(prog , arguments);
proc.waitForFinished();
tmp = proc.readAllStandardError() + proc.readAllStandardOutput();
exitStatus= proc.exitCode();
ui->textEdit->append(tmp +QString::number(exitStatus));The Results of running the code:
0
0
grep: âÂÂ: No such file or directory
2Actual desired info from the terminal output screen contents:
$ sudo -i$ sudo blkid
/dev/mmcblk0p1: SEC_TYPE="msdos" LABEL="boot" UUID="140A-14B7" TYPE="vfat"
/dev/mmcblk0p2: UUID="f24a4949-f4b2-4cad-a780-a138695079ec" TYPE="ext4"
$ /bin/bash -c ifconfig en1 | grep 'inet '
inet addr:192.168.1.65 Bcast:192.168.1.255 Mask:255.255.255.0
inet addr:127.0.0.1 Mask:255.0.0.0 -
Ok , now here is something about my keyboard layout . I have two sets of single quotes ' ' that come up when I click the single quote symbol . I am sure it's due to the limited O/S choices of keyboard layout that I seem to have this setup. Anyhow , I needed the single quotes that stick straight up in the arguments . Not the ones that are the reverse of these ` . Well , I just noticed that one now. I had fixed up the layout so most of the symbols worked correctly . I didn't notice this little anomily. Anyhow with the proper syntax . The following code all works properly. I think I feel more comfortable with the QProcess object now . So thanks again everyone !!!
QString prog;
QStringList arguments;
QProcess proc;
QString tmp;
int exitStatus;
prog="sudo ";
arguments <<"-i";
proc.start(prog , arguments);
proc.waitForFinished();
tmp = proc.readAllStandardError() + proc.readAllStandardOutput();
exitStatus= proc.exitCode();
ui->textEdit->append(tmp +QString::number(exitStatus));
arguments.clear();
prog="/bin/bash";
arguments <<arguments <<"-c" << "blkid";
proc.start(prog , arguments);
proc.waitForFinished();
tmp = proc.readAllStandardError() + proc.readAllStandardOutput();
exitStatus= proc.exitCode();
ui->textEdit->append(tmp +QString::number(exitStatus));
arguments.clear();
prog = "/bin/bash";
// arguments <<"-c" << "ifconfig en1 | grep 'inet ' | awk '{print $2}' | sed 's/addr://'";
arguments <<"-c" << "ifconfig eth0 | grep 'inet ' | awk '{print $2}' | sed 's/addr://'";
proc.start(prog , arguments);
proc.waitForFinished();
tmp = proc.readAllStandardError() + proc.readAllStandardOutput();
exitStatus= proc.exitCode();
ui->textEdit->append(tmp +QString::number(exitStatus)); -
QString prog = "/bin/bash"; QStringList arguments; arguments <<"-c" << "ifconfig en1 | grep 'inet ' | awk '{print $2}' | sed 's/addr://'"; QProcess proc; proc.start(prog , arguments); proc.waitForFinished(); qDebug() << proc.readAllStandardError() << proc.readAllStandardOutput();
Works fine on OS X.
Note that I don't allocate it on the heap, there's no need in this case. Also with your current code you have a memory leak since you don't delete your QProcess.
@SGaist said in QProcess not sending information back after it completes:
QString prog = "/bin/bash"; QStringList arguments; arguments <<"-c" << "ifconfig en1 | grep 'inet ' | awk '{print $2}' | sed 's/addr://'"; QProcess proc; proc.start(prog , arguments); proc.waitForFinished(); qDebug() << proc.readAllStandardError() << proc.readAllStandardOutput();
Works fine on OS X.
Note that I don't allocate it on the heap, there's no need in this case. Also with your current code you have a memory leak since you don't delete your QProcess.
Hi!
Trying to do the same experiment.
But "awk: fatal: cannot open file 'sed' for reading..." message in the console.
Command passed ok If I write this command in console directly only. -
Hi,
Use QProcess::setStandardOutputProcess. Make a QProcess for each command in the chain
-
Hi,
Use QProcess::setStandardOutputProcess. Make a QProcess for each command in the chain
@SGaist said in QProcess not sending information back after it completes:
Hi,
Use QProcess::setStandardOutputProcess. Make a QProcess for each command in the chain
Hi!
Something like this?QProcess pro1, pro2, pro3, pro4; QString com1, com2, com3, com4; com1 = "/bin/bash -c ifconfig eth0"; com2 = "grep 'inet'"; com3 = "awk '{print $2}'"; com4 = "sed 's/addr://'"; pro1.setStandardOutputProcess(&pro2); pro2.setStandardOutputProcess(&pro3); pro3.setStandardOutputProcess(&pro4); pro1.start(com1); pro2.start(com2); pro3.start(com3); pro4.start(com4);
-
@SGaist said in QProcess not sending information back after it completes:
Hi,
Use QProcess::setStandardOutputProcess. Make a QProcess for each command in the chain
Hi!
Something like this?QProcess pro1, pro2, pro3, pro4; QString com1, com2, com3, com4; com1 = "/bin/bash -c ifconfig eth0"; com2 = "grep 'inet'"; com3 = "awk '{print $2}'"; com4 = "sed 's/addr://'"; pro1.setStandardOutputProcess(&pro2); pro2.setStandardOutputProcess(&pro3); pro3.setStandardOutputProcess(&pro4); pro1.start(com1); pro2.start(com2); pro3.start(com3); pro4.start(com4);
@sitesv
If you do it this way your first command should read just:ifconfig eth0
because you are no longer sending the whole command line to
bash
.Don't forget you will need to split each command into the executable as one argument and the remaining command line parameters as separate arguments in a list.
And at that point you will need to drop the single quotes you still have around each argument, because those would have been interpreted by
bash
. So your three arguments will end up readinginet
(with or without a trailing space, you have changed your mind about that in what you have typed),{print $2)
ands/addr://
respectively (each as a single argument).By the time you do all of this, you might decide you'd rather do all three commands yourself: the
grep
+awk
+sed
are doing simple stuff you could just do yourself. You could just read the output fromifconfig eth0
as the onlyQProcess
you create and look through the text (see https://doc.qt.io/qt-5/qprocess.html#readAllStandardOutput), which would get rid of the complications of multiple processes if you wish. -
@sitesv
If you do it this way your first command should read just:ifconfig eth0
because you are no longer sending the whole command line to
bash
.Don't forget you will need to split each command into the executable as one argument and the remaining command line parameters as separate arguments in a list.
And at that point you will need to drop the single quotes you still have around each argument, because those would have been interpreted by
bash
. So your three arguments will end up readinginet
(with or without a trailing space, you have changed your mind about that in what you have typed),{print $2)
ands/addr://
respectively (each as a single argument).By the time you do all of this, you might decide you'd rather do all three commands yourself: the
grep
+awk
+sed
are doing simple stuff you could just do yourself. You could just read the output fromifconfig eth0
as the onlyQProcess
you create and look through the text (see https://doc.qt.io/qt-5/qprocess.html#readAllStandardOutput), which would get rid of the complications of multiple processes if you wish.@JonB said in QProcess not sending information back after it completes:
@sitesv
If you do it this way your first command should read just:ifconfig eth0
because you are no longer sending the whole command line to
bash
.Don't forget you will need to split each command into the executable as one argument and the remaining command line parameters as separate arguments in a list.
And at that point you will need to drop the single quotes you still have around each argument, because those would have been interpreted by
bash
. So your three arguments will end up readinginet
(with or without a trailing space, you have changed your mind about that in what you have typed),{print $2)
ands/addr://
respectively (each as a single argument).By the time you do all of this, you might decide you'd rather do all three commands yourself: the
grep
+awk
+sed
are doing simple stuff you could just do yourself. You could just read the output fromifconfig eth0
as the onlyQProcess
you create and look through the text (see https://doc.qt.io/qt-5/qprocess.html#readAllStandardOutput), which would get rid of the complications of multiple processes if you wish.Thank you for your answer!
QString prog1 = "sh", prog2 = "grep", prog3 = "awk", prog4 = "sed"; QProcess pro1, pro2, pro3, pro4; pro1.setStandardOutputProcess(&pro2); pro2.setStandardOutputProcess(&pro3); pro3.setStandardOutputProcess(&pro4); pro1.start(prog1, QStringList() << "-c" << "ifconfig eth0"); pro1.waitForFinished(); pro2.start(prog2, QStringList() << "inet "); pro2.waitForFinished(); pro3.start(prog3, QStringList() << "{print $2}"); pro3.waitForFinished(); pro4.start(prog4, QStringList() << "s/addr://"); pro4.waitForFinished(); QByteArray out1 = pro4.readAllStandardOutput(); QList<QByteArray> list1 = out1.split('\n'); foreach(auto str, list1){ qDebug() << str; }
But in the output stream only one string. In manual mode, there are three lines.
And this code runs for about 3 sec. Too much. -
@JonB said in QProcess not sending information back after it completes:
@sitesv
If you do it this way your first command should read just:ifconfig eth0
because you are no longer sending the whole command line to
bash
.Don't forget you will need to split each command into the executable as one argument and the remaining command line parameters as separate arguments in a list.
And at that point you will need to drop the single quotes you still have around each argument, because those would have been interpreted by
bash
. So your three arguments will end up readinginet
(with or without a trailing space, you have changed your mind about that in what you have typed),{print $2)
ands/addr://
respectively (each as a single argument).By the time you do all of this, you might decide you'd rather do all three commands yourself: the
grep
+awk
+sed
are doing simple stuff you could just do yourself. You could just read the output fromifconfig eth0
as the onlyQProcess
you create and look through the text (see https://doc.qt.io/qt-5/qprocess.html#readAllStandardOutput), which would get rid of the complications of multiple processes if you wish.Thank you for your answer!
QString prog1 = "sh", prog2 = "grep", prog3 = "awk", prog4 = "sed"; QProcess pro1, pro2, pro3, pro4; pro1.setStandardOutputProcess(&pro2); pro2.setStandardOutputProcess(&pro3); pro3.setStandardOutputProcess(&pro4); pro1.start(prog1, QStringList() << "-c" << "ifconfig eth0"); pro1.waitForFinished(); pro2.start(prog2, QStringList() << "inet "); pro2.waitForFinished(); pro3.start(prog3, QStringList() << "{print $2}"); pro3.waitForFinished(); pro4.start(prog4, QStringList() << "s/addr://"); pro4.waitForFinished(); QByteArray out1 = pro4.readAllStandardOutput(); QList<QByteArray> list1 = out1.split('\n'); foreach(auto str, list1){ qDebug() << str; }
But in the output stream only one string. In manual mode, there are three lines.
And this code runs for about 3 sec. Too much. -
@sitesv said in QProcess not sending information back after it completes:
And this code runs for about 3 sec. Too much.
Is it possible to fix this?
@sitesv
Yes. In that I already told the OP to do this via reading & parsing the output fromifconfig eth0
to do what thegrep
/awk
/sed
are doing, which is not that difficult. And thewaitForFinished()
s take an unknown amount of extra time too, probably. Then the only time spent will be however longifconfig eth0
takes, plus a few microseconds for reading it. If it takes any longer than that, you are doing something wrong.