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?


  • Moderators

    Hi!

    sh.start("bash --login");

    Are you sure this actually starts bash? Maybe try with "/bin/bash" and check the error().


  • Lifetime Qt Champion

    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?


  • Lifetime Qt Champion

    What exactly do you want to do with these variables ?

    Depending on your needs qgetenv and its friends might be more suited.



  • 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!



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.