Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Execute commands in git bash using QProcess



  • Hi ,
    Here is my snippet.

    QProcess* process = new QProcess(this);
    QString processArgs;

    processArgs ="C:\Program Files\Git\git-bash.exe";

    process->start(processArgs,QStringList());
    if (!process->waitForStarted()) {
    return;
    }
    qDebug()<< process->readAllStandardOutput() <<endl;

    process->write("ls\n\r");
    QByteArray output;
    if (process->waitForReadyRead()) {
    output += process->readAll();
    }
    qDebug() <<"OUTPUT : " << output;

    process->waitForFinished(-1);

    I am trying to open git bash and execute commands from the qt. I am able to open git bash but write is not happening . Is something wrong or is there any alternate way to execute commands .Thanks .....


  • Moderators

    Untested, guessing based on how Linux bash works: you should probably call git-bash.exe with -c argument followed by your command or script, like this:

    git-bash.exe -c "ls"
    

    Translated to QProcess lingo, that will be something like:

    process->start("git-bash.exe", {"-c", "'ls'"});
    


  • @Adithya
    You do not set any command to execute. That should be C:\Program Files\Git\git-bash.exe (it's not an argument), as @sierdzio shows.

    The simplest is to get it to do the ls and then exit. Similar to @sierdzio (I don't know if his syntax works, and his argument is not quite correct) that would be:

    process->start("C:\\Program Files\\Git\\git-bash.exe", QStringList() << "-c" << "ls"});
    process->waitForFinished(100000);
    auto out = process->readAllStandardOutput();
    auto err = process->readAllStandardError();
    

    If you really want to be able to send (multiple?) commands to a bash via write() your shown code needs changing a touch, but I won't bother unless you want this as bash -c is easier and may actually be what you want?

    You should always put in error checking/read anything from stderr, as these commands sometimes go wrong.


  • Moderators

    Oh right, - in my example was completely unnecessary.

    I don't know if his syntax works

    It does, starting with C++11.



  • @JonB Thanks for the help .And yes my intention is to run multiple commands in one session of git bash (That was the reason I was trying via write().) .



  • @sierdzio
    Hi.

    It wasn't just the hyphen in front of ls, it's the single-quotes there which I think would/might make it go wrong.

    What I actually meant about your syntax is that I know

    process->start(command, QStringList() << "-c" << "ls"});
    

    works, using QStringList() <<. If your shorter {"-c", "ls"} allows compiler to correctly infer overload argument type, I may consider using that in future replies. Does it work?!


  • Moderators

    @JonB said in Execute commands in git bash using QProcess:

    It wasn't just the hyphen in front of ls, it's the single-quotes there which I think would/might make it go wrong.

    Right, I was just trying to make it clear that -c expects a string argument (a script) and not a list of commands. But you are right, Qt will automatically double-quote it before passing it to the process.

    If your shorter {"-c", "ls"} allows compiler to correctly infer overload argument type, I may consider using that in future replies. Does it work?!

    Yes. It's really nothing unusual - C++11 list initialization. I use it regularly for QList, QVector, QHash, QMap.



  • @Adithya said in Execute commands in git bash using QProcess:

    And yes my intention is to run multiple commands in one session of git bash (That was the reason I was trying via write().) .

    Then we need a couple of minor modifications your original code:

    • process->start("C:\\Program Files\\Git\\git-bash.exe", QStringList());, or process->start("C:/Program Files/Git/git-bash.exe", QStringList());.
    • No arguments, though you should check the git-bash documentation to see if that wants any special arguments for your case where its input/output is piped.
    • process->write("ls\r\n");. Your order of the CR-LF is the wrong way round. I don't know whether you need the \r, or even if that will upset it and it wants \n only. You might want a "flush" after each write.
    • You call process->readAllStandardOutput() immediately after waitForStarted(), that is/could be too early.
    • You only call waitForReadyRead()/readAll() once. That is (potentially) not enough, output could come back in multiple, separate chunks.
    • You are relying on the output from the bash/command all being flushed from the other end for you to receive it. You had better hope their implementation does that! If you notice only partial data back to you, this could be the reason.
    • You are using the ("nasty") blocking/synchronous waitFor...() calls. If you run into trouble this way/things don't behave as you expect, change over to the asynchronous signals/slots methods of QProcess.
    • Don't forget to close your process/free it!

Log in to reply