Run command line from Qt app in linux
-
Where is your "myscript" located ?
-
Thanks SGaist
myscript is a file that makes use of the libraries loaded with xmip.bashrc
In fact, fact my post I tried to run myscript providing the absolute path. I mean
QProcess proc;
QString Command = " /home/grullo/xmip/build/myscript";
proc.start(Command);Then an error in the StdError appeared " error while loading shared libraries" that suggest me that the loaded libraries (by the first start process) are not available in the second start process. I think that the start processes are independent each other. I cannot load libraries for the second one. Currently the alternative I'm thinking is to create a bash script with all I need to do. Then I will run that script with just one start process.
I am correct with the idea of independent process?
Thanks in advacne
-
Yes you are because they are completely unrelated.
-
@grullo said in Run command line from Qt app in linux:
//Load the libraries (it is a script)
More than loading the libraries, it seems to me that you're setting the environment for such libraries to be found/used, setting the path, seeting some environment variables, etc. right?.
So I imagine you can run the first command (.bashrc script) and just grab the system environment just after it via QProcessEnvironment::systemEnvironment().
Then, use that QProcessEnvironment object that you received and used it to set the environment of the second process via QProcess::setProcessEnvironment
-
@Pablo-J-Rogina
It might depend exactly what you mean, but I don't think it can work. You cannot run the.bashrc
as aQProcess
from a Qt program and then useQProcessEnvironment::systemEnvironment()
to access the environment which was created in the sub-shell. ThesystemEnvironment
function returns the environment of the calling process (your Qt program), not that of the calledbash
which interprets the.bashrc
file.@grullo
Let us assume @Pablo-J-Rogina 's hunch is correct that you need the environment variables created inxmipp.bashrc
to be set when running yourmyscript
.Because you presently execute these two files as separate processes, your second command will not inherit anything from executing your first command.
What you may be looking for, try
proc.start("bash", QStringList() << "-c" << ". /home/grullo/xmip/xmipp.bashrc; /home/grullo/xmip/build/myscript");
or
proc.start("bash", QStringList() << "-c" << "source /home/grullo/xmip/xmipp.bashrc; /home/grullo/xmip/build/myscript");
Or, it is possible you could edit
/home/grullo/xmip/build/myscript
to gosource /home/grullo/xmip/xmipp.bashrc
as the first thing it does, and then you may able to executemyscript
alone from your Qt program. -
Thank's for your reply, what you said is exactly what it is. First I set some enviroments variables, to be used by the script.
What I could do is to create the shell script by code , and then call with the start the created script. This worked, but I know that's not a good or a very elegant solution.
Then I saw the @JonB solution, and I tested it. It works properly, and its the right solution (not mine dirty script solution) Thanks!. In fact what you propose I tried it without the bash -c, I think that's critical. Good to know it
Anyway I will spend some time trying to set the enviroment as @Pablo-J-Rogina suggested, just to learn.
Now I will try to read in real time the standardOutput.
Thank you to everyone!
-
@grullo said in Run command line from Qt app in linux:
Anyway I will spend some time trying to set the enviroment as @Pablo-J-Rogina suggested, just to learn.
Save time! My approach won't work
@JonB was exactly right. QProcess::systemEnvironment() returns the environment of the Qt app, i.e. the calling process and no sub-process can change the parent environment. That's why you need to source the initial script to alter the environment, since source is a shell built-in command that doesn't create another process... -
Thank you anyway @Pablo-J-Rogina.
Now I'm able to run scripts, I'm trying to read in real time the standard output. I'm finding some problems, but I will keep fighting them by myself. If for tomorrow I'm not able I will ask you help
Thank you everybody!
-
Dear all,
I continue fighting with my app... and I reached a point in which I'm stuck... Of course is again with the issue of launching a shell script. When I click on a button, the app launches an script. However, the script never finish, and always appears this error:
standard Error:
QProcess: Destroyed while process ("bash") is still running.If I run the script outside of Qt it finishes.
I copy here the code I have, just if it helps
QProcess proc;
proc.setWorkingDirectory("/home/grullo/isoXmipp/");
QString cmdline = ". /home/grullo/xmip-bundle/build/xmipp.bashrc";
QString xmipCmdLine;
createXmippScript(xmipCmdLine);
cmdline = cmdline + "; " + xmipCmdLine;
std::cout << cmdline.toStdString() << std::endl;
proc.start("bash", QStringList() << "-c" <<cmdline);
proc.waitForFinished();QString StdOut = proc.readAllStandardOutput(); //Reads standard output
ui->consoleOutput->setText(StdOut);
cout<<"\n standard output..........\n";
cout<<endl<<StdOut.toStdString();cout<<"\n standard error..........\n";
QString StdError = proc.readAllStandardError(); //Reads standard error
cout<<endl<<StdError.toStdString();Thanks in advance
-
@grullo said in Run command line from Qt app in linux:
QString cmdline = ". /home/grullo/xmip-bundle/build/xmipp.bashrc";
I guess the initial dot (".") is making your command line relative, so that path is not found when set the working directory.
In addition, it'd be useful if you handle signal errorOccurred as it helps knowing about any possible error.
-
@Pablo-J-Rogina
Hi Pablo. It's not what you say. If you read the discussion so far, you will discover that the OP's command-line (passed tobash -c
) is deliberately:. /home/grullo/xmip-bundle/build/xmipp.bashrc
There is a space after the dot. That is a
bash
/sh
command which is a synonym forsource
, and reads the following argument as a file of commands intobash
to be executed. Personally, while.
command may be convenient for typing at the keyboard, I would always usesource
in a program/script for clarity.@grullo
First, please do as @Pablo-J-Rogina asks and put a slot onerrorOccurred
signal. Please also check (and debug out) the return result fromproc.waitForFinished();
. Do yourself a favour, especially if you having a problem and trying to debug, always check documentation for functions having return results/error indicators and use them.The implication of the error message you see is that you have allowed the
QProcess proc;
variable to go out of scope while the process is still running. I don't see how that would arise from the code as shown, but there you are. If it were me, I'd try some other command-lines and see whether you always get this or whether it's only with your particular command.Ah, hang on.
bool QProcess::waitForFinished(int msecs = 30000)
times out by default after 30 seconds if not finished. You don't say anything, but I guess you have to wait 30 seconds and then you get the error? (You would have seen this from printing its return result, as I said above, please show us that.) In that case, your code will read any output and thenproc
will be destroyed. Your sub-process will still be running though, and you will get the message you see. Is that it? Assuming so, you need to decide what you're going to do if the process does not run to conclusion in 30 seconds. That is the most obvious explanation to me of what must be happening? You really ought not be usingwaitForFinished()
, and instead be doing it with signals and slots.... -
@JonB said in Run command line from Qt app in linux:
There is a space after the dot. That is a bash/sh command which is a synonym for source,
you're right. That's the problem to post an answer at midnight...
-
@Pablo-J-Rogina
:) It's also why choosing to writesource
rather than.
would make it clearer for the OP and anyone reading the code :) -
-