Команда работает в терминале, но не через QProcess

ifconfig | grep 'inet'

работает при исполнении через терминал. Но не через QProcess

Мой пример кода

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

Ничего не отображается на textedit.

но когда я использую толькоifconfig при запуске qprocess вывод выводится на textedit. Я пропустил какой-то трюк, чтобы построить командуifconfig | grep 'inet' нравится использовать\' за' а также\| за|? для специальных символов? но я тоже это попробовал :(

 Kamil Klimek22 мая 2012 г., 14:02
Правильно! полностью забыл об этом
 J-16 SDiZ22 мая 2012 г., 16:56
 Kamil Klimek22 мая 2012 г., 13:58
вам нужно указать полный путь для ifconifg. Ваше приложение имеет другую переменную PATH, чем ваш терминал
 J-16 SDiZ22 мая 2012 г., 16:53
Если вы хотите получить ipaddress, используйте правильный способ:qt-project.org/doc/qt-4.8/qnetworkinterface.html
 leemes22 мая 2012 г., 14:00
@KamilKlimek Поскольку это может быть проблемой для отдельных команд, в этом случае передача команд (которая не поддерживается QProcess) является реальной проблемой.

Ответы на вопрос(3)

Решение Вопроса

что вы пытаетесь сделать, это выполнитьshell commandне процесс. Передача команд является особенностью вашей оболочки.

Есть три возможных решения:

Поместите команду, которую вы хотите выполнить в качестве аргументаsh после-c (& Quot; команда & Quot;):

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

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

Или вы можете написать команды в качестве стандартного ввода дляsh:

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

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

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

Другой подход, который избегаетsh, чтобы запустить два QProcesses и выполнить конвейер в вашем коде:

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();
 27 мар. 2014 г., 12:15
Я считаю, что второй пример неверен: если вы запускаете оболочку и пишете в нее, вам также необходимо (1) отправлять команды в оболочку, добавляя символы новой строки и (2) завершать оболочку послеgrep команда выполнена, илиwaitForFinished() буду ждать вечно. Я провел быструю проверку, чтобы убедиться, что ваш код работает, и это не для меня, но исправьте меня, если я ошибаюсь :)
 27 мар. 2014 г., 14:29
@AkiRoss Закрытие stdin также выполнит то, что "в последней строке". Просто попробуйте в своем терминале:echo -n 'ifconfig | grep inet' | sh, гдеecho -n пропускает разрыв строки. Однако впоследствии он завершится, и канал между echo и sh закроет поток stdin sh.
 22 мая 2012 г., 14:07
Я добавил примеры кода для некоторых возможных решений.
 27 мар. 2014 г., 13:30
@AkiRoss Большое спасибо за ваш вклад, вы правы. (2): я думаю, проблема в том, чтоsh ждет больше команд на стандартный ввод. Вы должны закрыть канал stdin shsh.closeWriteChannel() между записью и ожиданием. (1): я на 95% уверен, что\n не обязательно. (1) + (2): если вы делаетеnot закрыть стандартный вводnot написать новую строку, кажется, ничего не происходит. Если вы это сделаете, команда будет выполнена, но только закрытие stdin sh'а завершит работу sh после выполнения. Поэтому, если мы решим (2), нам не нужно заботиться о (1). Если мы хотим выполнить несколько команд, мы должны исправить (1), но не (2).
 ScarCode22 мая 2012 г., 14:15
Grep сработал. Но я хочу передать вывод ifconfig в awk '/ inet / {gsub (/.*:/,& quot; & quot; ", $ 1); print $ 1}". который успешно напечатал некоторые o / p на терминале, а не через Qprocess. Я использовал меня 2 твоего решения

QProcess объект не дает автоматически полный синтаксис оболочки: вы не можете использовать каналы. Используйте оболочку для этого:

 22 мая 2012 г., 14:11
Ах да, это должны быть двойные кавычки, а не кавычки.
 ScarCode22 мая 2012 г., 14:05
Я тоже это попробовал. но все еще не работает !!
 22 мая 2012 г., 16:45
альтернатива (безопаснее, так как вам не нужно обращать внимание на экранирование внутри аргумента, если он более сложный): используйте QStringList для аргументов, например так:p1.start("/bin/sh", QStringList() << "-c" << "ifconfig | grep inet");

Однако естьsetStandardOutputProcess Метод, который направит вывод в следующий процесс.

Пример приведен в API.

Ваш ответ на вопрос