私はQtを使用していて、それをバッシュします。次のようなものを実行する必要があります。
bash: cat file | grep string
qtで:
QString cmd = "cat file | grep string";
QProcess *process = new QProcess;
process->start(cmd);
process->waitForBytesWritten();
process->waitForFinished();
qDebug() << process->readAll();
問題はパイプ( "|")にあり、プロセスは何も返しません。 ( "|")がない場合は、
"cat file"
全て大丈夫。 smthを試してみました。お気に入り
"cat file \\| grep string",
"cat file \| grep string"
しかし、結果は同じです。コマンドをコピーしてbashで実行すると、すべて問題ありません。
QString::toAscii().data()
そして他の変換も悪い結果をもたらします。
問題は、QProcessでシステムコマンドを実行できず、単一のプロセスしか実行できないことです。したがって、回避策は、コマンドを引数としてbashに渡すことです。
process.start("bash", QStringList() << "-c" << "cat file | grep string");
迅速で汚いハックはこれです:
_QString cmd = "/bin/sh -c \"cat file | grep string\"";
_
C++ 11の_R""
_を使用してそこにエスケープすることを回避することもできますが、重要なのは、bashでのみ機能するため、そこでbash
を使用しないことです。 bash、単にash、またはその他の一般的なデスクトップシェルなしでbusyboxが埋め込まれた場合は機能しません。
_/bin/sh
_は通常、使用されるシェルインタープリターへのシンボリックリンクであるため、最終的には機能します。
しかし!
Qtなどの高レベルのC++/OOPフレームワークを使用する場合、少し低レベルを考えていると思います。 bashからコマンドを実行するときに、低レベルの方法でコマンドを呼び出すことはお勧めしません。このユースケースには、専用の高レベルの便利なAPIがいくつかあります。
公式ドキュメント に基づいて、QProcessはパイプされたコマンドに対して機能することになっています:
void QProcess :: setStandardOutputProcess(QProcess * destination)
このプロセスの標準出力ストリームを宛先プロセスの標準入力にパイプします。
つまり、command1 | command2シェルコマンドコマンドは、次の方法で実行できます。
_QProcess process1;
QProcess process2;
process1.setStandardOutputProcess(&process2);
process1.start("cat file");
process2.start("grep string");
process2.setProcessChannelMode(QProcess::ForwardedChannels);
// Wait for it to start
if(!process1.waitForStarted())
return 0;
bool retval = false;
QByteArray buffer;
while ((retval = process2.waitForFinished()));
buffer.append(process2.readAll());
if (!retval) {
qDebug() << "Process 2 error:" << process2.errorString();
return 1;
}
qDebug() << "Buffer data" << buffer;
_
これは重要なポイントではありませんが、有用な提案です。QString::toAscii()
を使用しないでください。そのAPIはQt5で非推奨になりました。
問題は、process-> start(cmd)を呼び出すと、catの呼び出しに続くコマンドがすべてcatへの引数として解釈されるため、パイプが期待どおりに動作しないことです。文字列のパラメータを使用してbashを呼び出すことから始めると、必要なものが得られるはずです。
QString cmd = "bash -c \"cat file | grep string\"";
または、「cat file」を呼び出して、QProcessからの出力を読み取るときに、返されたQStringを検索することもできます。
これはどう :
QString program = "program";
QStringList arguments;
download = new QProcess(this);
download->start(program, arguments);