3

I need to force my c++ QT4 application to read results from a linux command. I am trying to use Qprocess but as soon as my command gets complicated it get messed somehow (just guessing) and does not work.

Here i try to make for yu a small example:

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;

this will print:

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

while would correctly print the file names if runed from the consol.

If i replace the comman with somethink simpler such command = "ls -l"; it work smoothless The error is returned on standar error by the OS.

I guess thereforethat the Qstring used for the command gets manipolated somehow. Any idea about wht's happening?

Stefano
  • 3,981
  • 8
  • 36
  • 66

4 Answers4

7

QProcess does not support shell commands. The pipe symbols is thus not interpreted by a shell, but instead directly passed to ls. ls interprets it as file name, and complains because apparantly there is no file named |.

You need to setup pipes manually by redirecting input and output streams of QProcess objects. Read the documentation to learn how to do this.

Generally how should avoid shell commands, and instead rely on Qt classes and functions. There is certainly no need to call grep or ls, because the same can be done easier with QRegExp, and QDir. If you need to execute subprocesses, then use the ::start(const QString&, const QStringList&, OpenMode) overload and pass all arguments as list to avoid quoting issues.

  • i do not think it's just the |. if i use command egrep -l 'aaa' /user/*/mydir/* says egrep: /user/*/mydir/* No such file or directory. and in ths command i have no | – Stefano Sep 29 '11 at 12:22
  • 3
    Same problem. The * wildcard is also interpreted by the shell. What happens on the shell is, that the wildcard is replaced and the command is called with all matching files. If you use QProcess no such replacement is done and grep is called as egrep "/user/*/mydir/*" (note the ", i.e. the pattern is given to egrep as a parameter). Try this with the " on the shell and you will have the same problems. – LiKao Sep 29 '11 at 13:13
4

Try this :

Run shell from QProcess and pass arguments to shell. Example :

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

Let me know is this worked or not .

O.C.
  • 6,711
  • 1
  • 25
  • 26
0
command = "ls -l | grep a | sort";

isn't actually a process but pipeline of 3 different processes: ls, grep and sort.

GreenScape
  • 7,191
  • 2
  • 34
  • 64
0

thanks all guys for the help.

in order to do what i needed i had to change the aproach using:

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);
}
Stefano
  • 3,981
  • 8
  • 36
  • 66
  • 1
    -1. `QProcess` can perfectly do the same, there is no need to resort to C functions. –  Sep 29 '11 at 16:37
  • If this answer solved your problem, you should accept it instead of accepting the other one. –  May 15 '13 at 04:58