Qt not reading shell variables
-
I've been working on this for some time, but can not find a suitable workaround.
I have set JAVA_HOME and PATH on Linux. From the terminal everything works fine.
"echo $JAVA_HOME" outputs the jdk-directory.From within QtCreator with qgetenv("JAVA_HOME") outputs nothing, same goes for QProcessEnvironment::systemEnvironment().
When I start QtCreator or my Qt application from the command-line, it does see the JAVA_HOME.
So I tried the following:QProcess sh; sh.start("bash --login"); sh.write("source /home/jan-willem/.bashrc\n"); sh.write("env"); sh.closeWriteChannel(); sh.waitForFinished(); QByteArray output = sh.readAllStandardOutput(); QByteArray error = sh.readAllStandardError(); sh.close(); qDebug() << output << error;
It did not work. Only the system wide variables are shown.
When I insert:sh.write("export JAVA_HOME=/opt/java/jdk1.8.0_121\n");
it does work (obviously), but the idea is to check the environment variables to find the jdk-path, and not the other way around.
Someone an idea?
-
Hi!
sh.start("bash --login");
Are you sure this actually starts bash? Maybe try with "/bin/bash" and check the
error()
. -
Hi,
To add to @Wieland, if you are looking for the environment variables of your process then QProcess::processEnvironment might be of interest.
-
@Wieland and @SGaist
I've modified the code as follows:
QProcess sh; sh.start("/bin/bash"); // or /bin/bash --login, bash or bash --login qDebug() << sh.error(); // QProcess::ProcessError(UnknownError) QProcessEnvironment pe = sh.processEnvironment(); qDebug() << pe.value("PATH"); // returns nothing // sh.waitForFinished(); commented out because it freezes the GUI at this point sh.close();
And
QProcess sh; sh.setProcessEnvironment(QProcessEnvironment::systemEnvironment()); sh.start("/bin/bash"); // or /bin/bash --login, bash or bash --login qDebug() << sh.error(); // QProcess::ProcessError(UnknownError) QProcessEnvironment pe = sh.processEnvironment(); qDebug() << pe.value("PATH"); // returns "/opt/Qt/5.8/gcc_64/bin:/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" // sh.waitForFinished(); commented out because it freezes the GUI at this point sh.close();
The .profile and .bashrc are for some reason not read. Perhaps it has something to do with the unknown error. I will try to find out what this error is.
By the way, I noticed that the System Environment Variables in QtCreator also don't include the shell variables. I read somewhere that apps started from the desktop environment don't use bash or something to launch, which explains why QtCreator doesn't recognize the exported variables from .bashrc.
But using a QProcess like above would normally be a good way to find those variables, am I right?
-
For my work I have to learn programming in Java. So as a fun-project (taking a break from studying) I created a code-editor using only Qt-examples and the Matching Parentheses example from the Qt Quarterly. I want to implement something like a first-run wizard which looks for a JAVA_HOME or ask the user to select the path to the JDK.
qgetenv("PATH"); also just gives me "/opt/Qt/5.8/gcc_64/bin:/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games". It was the first thing I tried ;-)
As I said before, hen I start QtCreator or my Qt application from the command-line, it uses bash and therefore sees the JAVA_HOME variable.
So, I could try find out what (gui-)shell launches QtCreator and other apps and perhaps see how ta export the shell variables to that shell also. But I thought starting bash form a QProcess should also work.
-
Well, actually it does work! But if bash is not running interactively, it won't read the .bashrc where the shell-variables are stored. So I did the following:
sh.start("bash -i"); // the -i tell bash to run interactively if(sh.waitForStarted()) sh.write("printenv JAVA_HOME"); // or sh.write("echo $JAVA_HOME") sh.closeWriteChannel();
In case you were wondering, I connected the QProcess::finished signal to a slot where the QProcess::readAllStandardOutput is put in a QPlainTextEdit.
The QProcess::processEnvironment is not updated however. Even if I try to export JAVA_HOME with sh.write("export JAVA_HOME"). While that is not what I expected, I now can find the local shell-variables.
So I will mark this problem as solved.
Thanks!