Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/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;
        process->setWorkingDirectory(path);
        connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(processOutput()));
        connect(process, SIGNAL(readyReadStandardError()), this, SLOT(processError()));
        process->start(cmd);
        ...
    }
    
    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 file.zip -xi (git ls-files | tr "\n" " ")
    

  • Qt Champions 2019

    @sonichy Please read documentation and use QProcess in a proper way: https://doc.qt.io/qt-5/qprocess.html
    Also, if it does not work then at least connect a slot to https://doc.qt.io/qt-5/qprocess.html#errorOccurred and check whether it is called and what the error is. Also https://doc.qt.io/qt-5/qprocess.html#stateChanged 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

    Hi,

    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;
    process1->setStandardOutputProcess(process2);
    process1->setWorkingDirectory(path);
    process2->setWorkingDirectory(path);
    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;
    process1->setWorkingDirectory(path);
    connect(process1, SIGNAL(readyReadStandardError()), this, SLOT(processError()));
    process1->start("git ls-files");
    process1->waitForFinished();
    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()));
    process1->start(s);
    if(process1->waitForFinished())
        genList(path);
    

Log in to reply