Important: Please read the Qt Code of Conduct -

QProcess: git ls-files | zip

  • I want to pack git files on Linux, and terminal work fine.

    git ls-files | xargs tar -czvf file.tar.gz

    But QProcess has no response no output no error.

        QString cmd = "git ls-files | xargs tar -czvf " + QFileInfo(path).fileName() + ".tar.gz";
        qDebug() << cmd;
        QProcess *process = new QProcess;
        connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(processOutput()));
        connect(process, SIGNAL(readyReadStandardError()), this, SLOT(processError()));
    void MainWindow::processOutput()
        QProcess *process = qobject_cast<QProcess*>(sender());
        QString s = QString(process->readAllStandardOutput());
        qDebug() << s;
    void MainWindow::processError()
        QProcess *process = qobject_cast<QProcess*>(sender());
        QString s = QString(process->readAllStandardError());
        qDebug() << s;

    And how to use zip command instead?
    (...) run first

    zip -xi (git ls-files | tr "\n" " ")

  • Qt Champions 2019

    @sonichy Please read documentation and use QProcess in a proper way:
    Also, if it does not work then at least connect a slot to and check whether it is called and what the error is. Also can help.
    Do not mix command and its parameters in one string when calling start. The documentation shows how to do it properly:

    QString program = "./path/to/Qt/examples/widgets/analogclock";
    QStringList arguments;
    arguments << "-style" << "fusion";
    QProcess *myProcess = new QProcess(parent);
    myProcess->start(program, arguments);

    "And how to use zip command instead?" - man zip

  • Lifetime Qt Champion


    To add to @jsulm, since you are piping several commands, take a look at setStandardOutputProcess.

  • @sonichy
    You cannot send git ls-files | xargs tar -czvf file.tar.gz to QProcess to execute. You do not intend it to be a single command, it is 2 commands. Any "command" containing tokens such as |, >, <, & etc. cannot in itself be executed as one command. If you try, say, QProcess::execute('ls | cat') you should get messages like:

    /usr/bin/ls: cannot access '|': No such file or directory
    /usr/bin/ls: cannot access 'cat': No such file or directory

    showing the | & cat have been passed as arguments to the ls, which is not what you intended.

    You have two choices:

    1. Set up multiple QProcesss --- one for the git ls-files, another for the xargs tar -czvf ... --- and connect the output of the first to the input of the second (setStandardOutputProcess()).

    2. Wrap your command into a single string to be executed by the shell, which is what processes the | token, e.g.:

    process->start("/bin/sh", QStringList() << "-c" << "git ls-files | xargs tar -czvf " + QFileInfo(path).fileName() + ".tar.gz");

    You do have be careful that you know the shell quoting rules for the argument passed after -c in this case, yours will probably work as I have shown. This way you have a single command, whose output you can capture in the normal way.

  • @SGaist tar.gz solved !

    QProcess *process1 = new QProcess;
    QProcess *process2 = new QProcess;
    connect(process1, SIGNAL(readyReadStandardOutput()), this, SLOT(processOutput()));
    connect(process1, SIGNAL(readyReadStandardError()), this, SLOT(processError()));
    connect(process2, SIGNAL(readyReadStandardOutput()), this, SLOT(processOutput()));
    connect(process2, SIGNAL(readyReadStandardError()), this, SLOT(processError()));
    process1->start("git ls-files");
    process2->start("xargs tar -czvf " + QFileInfo(path).fileName() + ".tar.gz");

  • @JonB zip solved !

    QProcess *process1 = new QProcess;
    connect(process1, SIGNAL(readyReadStandardError()), this, SLOT(processError()));
    process1->start("git ls-files");
    QString s = QString(process1->readAllStandardOutput()).replace("\n"," ");
    qDebug() << s;
    s = "zip " + QFileInfo(path).fileName() + ".zip -xi " + s;
    qDebug() << s;
    connect(process1, SIGNAL(readyReadStandardOutput()), this, SLOT(processOutput()));

Log in to reply