Comando que funciona en la terminal, pero no a través de QProcess

ifconfig | grep 'inet'

está funcionando cuando se ejecuta a través de la terminal. Pero no a través de QProcess

Mi código de muestra es

QProcess p1;
p1.start("ifconfig | grep 'inet'");
p1.waitForFinished();
QString output(p1.readAllStandardOutput());
textEdit->setText(output);

No se muestra nada en textedit.

pero cuando uso solo ifconfig al inicio de qprocess, la salida se muestra en textedit. ¿Me perdí algún truco para construir el comando? ifconfig | grep 'inet' , como uso \' para ' y \| para |? para caracteres especiales? pero también lo intenté :(

preguntado el 22 de mayo de 12 a las 12:05

debe especificar la ruta completa para ifconifg. Su aplicación tiene una variable PATH diferente a su terminal:

@KamilKlimek Como este podría ser el problema para los comandos únicos, en este caso, la canalización de los comandos (que no es compatible con QProcess) es el verdadero problema. -

¡Correcto! Me olvidé por completo de ese -

Si desea obtener una dirección IP, use la forma adecuada: qt-project.org/doc/qt-4.8/qnetworkinterface.html -

3 Respuestas

QProcess ejecuta un solo proceso. Lo que estás tratando de hacer es ejecutar un comando de shell, no un proceso. La canalización de comandos es una característica de su shell.

Hay tres posibles soluciones:

Ponga el comando que desea que se ejecute como argumento para sh después de -c ("mando"):

QProcess sh;
sh.start("sh", QStringList() << "-c" << "ifconfig | grep inet");

sh.waitForFinished();
QByteArray output = sh.readAll();
sh.close();

O puede escribir los comandos como la entrada estándar para sh:

QProcess sh;
sh.start("sh");

sh.write("ifconfig | grep inet");
sh.closeWriteChannel();

sh.waitForFinished();
QByteArray output = sh.readAll();
sh.close();

Otro enfoque que evita sh, es lanzar dos QProcesses y hacer la canalización en su código:

QProcess ifconfig;
QProcess grep;

ifconfig.setStandardOutputProcess(&grep); // "simulates" ifconfig | grep

ifconfig.start("ifconfig");
grep.start("grep", QStringList() << "inet"); // pass arguments using QStringList

grep.waitForFinished(); // grep finishes after ifconfig does
QByteArray output = grep.readAll(); // now the output is found in the 2nd process
ifconfig.close();
grep.close();

respondido 27 mar '14, 12:03

Grep funcionó. Pero quiero canalizar la salida de ifconfig a awk '/inet/{gsub(/.*:/,"",$1);print$1}'. que imprimió con éxito algunos o/p en la terminal y no a través de Qprocess. Me usé thod 2 de su solución - Código de cicatriz

Deberías preferir el tercer método. Para argumentos complicados, debe pasarlos usando una QStringList como hice en el primer ejemplo. Actualizaré el tercer método para darte una idea. - lemes

Creo que el segundo ejemplo es incorrecto: si inicia el shell y escribe en él, también necesita (1) enviar comandos al shell agregando líneas nuevas y (2) terminar el shell después de la grep comando ejecutado, o waitForFinished() esperará para siempre. Hice una prueba rápida para verificar si su código funcionó, y no funcionó para mí, pero corríjame si me equivoco :) - akiross

@AkiRoss Muchas gracias por tu aporte, tienes razón. (2): Supongo que el problema es que sh espera más comandos en stdin. Deberías cerrar el canal estándar de sh con sh.closeWriteChannel() entre escribir y esperar. (1): Estoy 95% seguro de que el \n no es necesario. (1)+(2): Si lo hace no cerrar stdin, y hacer no escriba una nueva línea, nada parece suceder. Si lo hace, el comando se ejecuta, pero solo cerrar el stdin de sh cerrará sh después de la ejecución. Entonces, si resolvemos (2), no necesitamos preocuparnos por (1). Si quisiéramos ejecutar múltiples comandos, deberíamos arreglar (1) pero no (2). - lemes

@AkiRoss Closing stdin también ejecutará lo que está "en la última línea". Simplemente pruébalo en tu terminal: echo -n 'ifconfig | grep inet' | sh, Donde echo -n omite el salto de línea. Sin embargo, terminará después, y la tubería entre echo y sh cerrará la transmisión estándar de sh. - lemes

La QProcess object no le proporciona automáticamente una sintaxis de shell completa: no puede usar tuberías. Usa un caparazón para esto:

p1.start("/bin/sh -c \"ifconfig | grep inet\"");

Respondido el 12 de diciembre de 12 a las 13:12

Ah, sí, deberían ser comillas dobles, no comillas. - kmkaplan

alternativa (más segura ya que no tiene que prestar atención a escapar dentro del argumento, si es más complicado): use QStringList para los argumentos, así: p1.start("/bin/sh", QStringList() << "-c" << "ifconfig | grep inet"); - lemes

Parece que no puede usar el símbolo de tubería en QProcess.

Sin embargo existe la setStandardOutputProcess Método que canalizará la salida al siguiente proceso.

Se proporciona un ejemplo en la API.

contestado el 22 de mayo de 12 a las 13:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.