Solved 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 firstzip file.zip -xi (git ls-files | tr "\n" " ")
-
@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
-
Hi,
To add to @jsulm, since you are piping several commands, take a look at setStandardOutputProcess.
-
@sonichy
You cannot sendgit ls-files | xargs tar -czvf file.tar.gz
toQProcess
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 thels
, which is not what you intended.You have two choices:
-
Set up multiple
QProcess
s --- one for thegit ls-files
, another for thexargs tar -czvf ...
--- and connect the output of the first to the input of the second (setStandardOutputProcess()
). -
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);