elif mutlu elif mutlu - 29 days ago 24
Linux Question

Ampersand(&) (very command execute) with QProcess

I'm using Qt and tcsh over it, need to execute something like:

tcsh: pwd & ls


in Qt:

QString cmd = "pwd & ls";
QProcess *process = new QProcess;
process->start(cmd);
process->waitForBytesWritten();
process->waitForFinished();
qDebug() << process->readAll();`


The problem is in ampersand ("&"), and process returns nothing.

Answer

First, let's figure out what happens when you execute a single command, like pwd. When you do it, the shell process forks (i.e. produces a child process), then the child process turns into pwd process and acquires control over the terminal.

Next, if you execute pwd &, all the same happens, but the child process (pwd in our example) does not get control over the terminal. It runs as a background process, while the shell continues to work with the terminal. For example, you may run a GUI program (firefox &), and the shell will be ready to run the next one immediately.

Finally, when you execute pwd & ls, all the same as in the previous case happens, but the shell forks one more time and runs ls in foreground. As you might guess, pwd & ls & yields both processes being run in background, and you may execute as many commands as you want at once.

Now let's get back to Qt. QProcess does not run any shell before running the command. Thus, when you run pwd & ls via QProcess, pwd will be the only program executed, but it will get two command line arguments: & and ls. Both of them will be ignored.

So the equivalent of pwd & ls will be two QProcess objects, each running a single command.

Another solution is to run the shell explicitly to make the arguments being parsed:

QString cmd = "tcsh -c \"pwd & ls\"";
QProcess *process = new QProcess;
process->start(cmd);
process->waitForBytesWritten();
process->waitForFinished();
qDebug() << process->readAll();