qprocess получает поведение, подобное оболочке

Я использую QT в приложении Windows (не знаю, имеет ли это значение) и хочу запустить какой-то процесс из своего приложения, используя QProcess. (фактически через оболочку qtscript, которая использует QProcess)

Кажется, это работает, но у меня возникают проблемы при использовании более продвинутых командных строк, таких как подключение программ с использованием каналов.

Если я запускаю процесс, используя следующие строки программы:

QProcess proc;
QString command = "grep \"false negatives\" test.txt | cut -f2";
proc.start(command);

Команда grep жалуется, что не может найти файл «2». поэтому очевидно, что командная строка не интерпретируется так, как я ожидал.

если я префикс cmd /C к команде, она работает хорошо, но это, очевидно, больше не зависит от ОС и может иметь некоторые дополнительные предостережения относительно параметра командной строки.

Есть ли какой-нибудь Qt-подобный способ справиться с этим и заставить Qt использовать какой-то интерпретатор командной строки по умолчанию?


person vlad_tepesch    schedule 15.01.2015    source источник
comment
возможный дубликат Невозможно выполнить команду echo в QProcess   -  person TheDarkKnight    schedule 15.01.2015
comment
@ Merlin069 это не дубликат. Вопрос в другом. Ответ на связанный вопрос (вызов команды через оболочку) уже упоминается в моем вопросе.   -  person vlad_tepesch    schedule 15.01.2015
comment
Пожалуйста, покажите полный вызов запуска QProcess, а не только параметры командной строки.   -  person TheDarkKnight    schedule 15.01.2015
comment
@ Merlin069 сделано, но в этом нет ничего особенного.   -  person vlad_tepesch    schedule 15.01.2015
comment
Просто вызовите bash -c command1 | команда2 или cmd /c команда1 | command2 или любой другой правильный формат.   -  person sashoalm    schedule 20.01.2015


Ответы (1)


Есть ли какой-нибудь Qt-подобный способ справиться с этим и заставить Qt использовать некий интерпретатор командной строки по умолчанию?

Простой ответ: нет, интерпретатора командной строки Qt по умолчанию не существует.

QString command = "grep \"false negatives\" test.txt | cut -f2";

Эта команда не работает, потому что QProcess берет первый токен (grep) и использует его в качестве команды, а затем передает этой команде каждый элемент, разделенный пробелом. В этом случае команда pipe не является допустимым аргументом для grep и не является ни cut, ни -f2.

Я прокомментировал, что ответ на этот вопрос был возможно аналогично, так как демонстрирует, как можно успешно использовать команду pipe с QProcess; обратите внимание, что аргументы заключены в кавычки.

Поскольку вы не хотите вызывать cmd или эквивалент *nix, такой как bash, вы можете справиться с этим двумя вызовами QProcess; первый для команды grep и второй для вырезания, передавая вывод из первого вызова QProcess.

Функция QProcess::setStandardOutputProcess упрощает эту задачу, позволяя для создания канала непосредственно между двумя объектами QProcess.

Поэтому вы бы сделали что-то вроде этого: -

QProcess proc1;
QProcess proc2;

proc1.setStandardOutputProcess(&process2);

QString cmd1("grep \"false negatives\" test.txt");
QString cmd2("cut -f2");

proc1.start(cmd1);
proc2.start(cmd2);
person TheDarkKnight    schedule 15.01.2015
comment
фактическая командная строка определяется пользователем сценарием, который вызывает оболочку QProcess из JavaScript. - person vlad_tepesch; 15.01.2015
comment
Затем проанализируйте командную строку, ища любые каналы; если вы их найдете, вы знаете, что вам нужно создать новый QProcess, разделить строку и установить стандартный вывод, связав их по мере необходимости. - person TheDarkKnight; 15.01.2015
comment
это не так просто, так как разделитель аргументов различается в разных системах (Windows не поддерживает одинарные кавычки) символы канала могут встречаться в аргументах как обычные текстовые символы (регулярные выражения)... много предостережений, на которые никто не обращает внимания, пока кто-нибудь не наткнется их. следующая вещь после каналов - это перенаправление входных и выходных файлов или перенаправление каналов ошибок ... много вещей, которые уже реализованы в обычной оболочке. Зачем его переделывать? (взгляните на tldp.org/HOWTO/Bash-Prog-Intro -HOWTO-3.html) - person vlad_tepesch; 15.01.2015
comment
На вашем месте я бы просто использовал #ifdef _PLATFORM и вызвал соответствующий интерпретатор командной строки, передав строку напрямую. Если вы используете Windows, OS X и Linux, у вас есть только два интерпретатора; cmd и bash, или любой другой *nix, который вы предпочитаете. - person TheDarkKnight; 15.01.2015
comment
да, это очевидный способ сделать. Я надеялся, что что-то базовое покрывается некоторыми вещами Qt. Но, конечно, это функции, специфичные для ОС, которые не обязательно совместимы (но, к счастью, самые основные вещи, такие как перенаправления stdout/stderr (файл и каналы) совместимы) - person vlad_tepesch; 15.01.2015