0

I am using QT in a windows (do not know if that matters) application and want to start some process from my application using QProcess. (actually through a qtscript wrapper that uses QProcess)

This seems to work but i have problems when using more advanced command lines like connecting programms using pipes.

If i start a process using the following program lines:

QProcess proc;
QString command = "grep \"false negatives\" test.txt | cut -f2";
proc.start(command);

The grep command complains that it could not find the file "2". so obviously the command line is not interpreted as i would expect it to do.

if i prefix a cmd /C to the command it works well but this obviously is not OS independent anymore and may have some additional caveats regarding command line parameter.

Is there any Qt like way to handle that and force Qt to use some default command line interpreter?

vlad_tepesch
  • 6,681
  • 1
  • 38
  • 80

1 Answers1

2

Is there any Qt like way to handle that and force Qt to use some default command line interpreter?

The simple answer is no, there isn't a Qt default command line interpreter

QString command = "grep \"false negatives\" test.txt | cut -f2";

This command doesn't work because QProcess takes the first token (grep) and uses that as the command, then passes each item, separated by a space to that command. In this case, the pipe command is not a valid argument for grep and neither is cut, nor -f2.

I commented that the answer to this question was possibly similar, as it demonstrates how you can successfully use the pipe command with QProcess; note that the arguments are surrounded by quotes.

As you don't want to call cmd or a *nix equivalent such as bash, you can handle this with two calls to QProcess; the first for the grep command and the 2nd for the cut, passing in the output from the first QProcess call.

The function QProcess::setStandardOutputProcess makes this easier, allowing you to create the pipe directly between the two QProcess objects.

Therefore you'd do something like this: -

QProcess proc1;
QProcess proc2;

proc1.setStandardOutputProcess(&process2);

QString cmd1("grep \"false negatives\" test.txt");
QString cmd2("cut -f2");

proc1.start(cmd1);
proc2.start(cmd2);
Community
  • 1
  • 1
TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
  • the actual command string is user defined by the script that invokes the QProcess wrapper from the JavaScript. – vlad_tepesch Jan 15 '15 at 15:10
  • Then parse the command string, looking for any pipes; if you find them, you know you have to create a new QProcess, split the string and set the standard output, chaining them as required. – TheDarkKnight Jan 15 '15 at 15:12
  • that is not that easy since the argument delimiter are different on different systems (windows does not support single quotes) pipe-symbols may occure in Arguments as normal text symbols (regex)... a lot of caveats one never minds until someone stumbles across them. the next thing after pipes are input and output file redirections or redirections of error channels... a lot of things a normal shell allready has implemented. Why should one reimplement it? (take a look at http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html) – vlad_tepesch Jan 15 '15 at 15:17
  • 1
    If I were you I'd simply use #ifdef _PLATFORM and call the relevant command line interpreter, passing the string directly. If you're using Windows, OS X and linux, you only have two interpreters; cmd and bash, or whichever *nix one you prefer. – TheDarkKnight Jan 15 '15 at 15:20
  • yes thats the obvious way to do. My hope was that something that basic is covered by some Qt stuff. But of course that are OS-specific functions that are not necessarily compatible (but luckily the most basic things like stdout/stderr redirections (file and pipes) are) – vlad_tepesch Jan 15 '15 at 15:30