Russian Qt Forum

Qt => Общие вопросы => Тема начата: Hoblin от Август 10, 2010, 16:29



Название: QProcess: запуск процесса с помощью "sh -c"
Отправлено: Hoblin от Август 10, 2010, 16:29
Есть задача: запустить некоторый bash-скрипт, хранящийся в памяти, не прибегая к помощи временных файлов. Скрипт поступает в функцию в виде большой QString-строки. Нам нужно, чтобы выполнилось что-то вроде:
Код:
$ sh -c "текст_скрипта"

В скрипте могут быть пробелы, кавычки и пр., поэтому, подавая его в команду, я использую конструкцию:
Код:
$ sh -c "`cat << EOF
текст скрипта
EOF`"

Всё работает, до тех пор, пока я не откладываю bash и не пытаюсь сделать то же самое на Qt:
Код:
QString command = "sh -c \"`cat <<EOF\n" + scriptText + "\nEOF`\"";
process->start(command);
Вот так - не работает. При этом, если я вывожу какой-нибудь отладочный
cout << command.toUtf8() << endl;
то получаю точную копию bash-кода из листинга №2 моего сообщения. Копирую, вставляю в консоль - работает.


Название: Re: QProcess: запуск процесса с помощью "sh -c"
Отправлено: Пантер от Август 10, 2010, 16:42
В QProcess в качестве комманды передавай sh, а остальное передавай как параметры в QStringList.


Название: Re: QProcess: запуск процесса с помощью "sh -c"
Отправлено: Hoblin от Август 10, 2010, 17:12
А разве есть разница?

Переделал на:
Код:
stringList = "-c \"`cat <<EOF\n" + scriptText + "\nEOF`\"";
process->start("su", stringList);
Ничего не изменилось. Да и сама команда формируется же визуально правильно. А вот почему не отрабатывает - для меня загадка.


Название: Re: QProcess: запуск процесса с помощью "sh -c"
Отправлено: Alex Custov от Август 10, 2010, 18:20
А разве есть разница?

Переделал на:
Код:
stringList = "-c \"`cat <<EOF\n" + scriptText + "\nEOF`\"";
process->start("su", stringList);
Ничего не изменилось. Да и сама команда формируется же визуально правильно. А вот почему не отрабатывает - для меня загадка.

Разница есть. Когда ты передаёшь одну строку, Qt само разбирает на аргументы. При использовании stringlist - нет.

Код
C++ (Qt)
   QString scriptText =
"#!/bin/sh\n"
"\n"
"#\n"
"# Script to do someting\n"
"#\n"
"\n"
"echo \"do your work here\"\n"
"\n"
"exit 0\n"
;
   QStringList stringList = QStringList() << "-c" << scriptText;
 
   p.start("sh", stringList);
   p.waitForFinished();
 


Название: Re: QProcess: запуск процесса с помощью "sh -c"
Отправлено: sendevent от Август 11, 2010, 01:46
присоединяюсь: аргументы передаем списком строк - и все ок, возможно надо подправить само тело скрипта (кавычки-бекслеши).
двойная вложенность (git log --pretty=format:blah-blah-blah+ wc/grep) - работают на ура.
Код:
//-- test-qprocess, main.cpp:
...
    QProcess *pProcess = new QProcess();
    pProcess->start( QObject::tr( "/bin/sh" ), QStringList()
                   << QObject::tr( "-c" )
                   << QObject::tr ( "echo $(pidof %1)" ).arg( argv[0]) );

    if( pProcess->waitForStarted() )
    {
        pProcess->waitForFinished();
        qDebug( "%s", qPrintable( pProcess->readAllStandardOutput() ) );
    }
...
Цитата: stdout
bash-4.1$ ./test-qprocess
4860

кстати, хоть разница и есть - возможно, с первого раза не видна, поэтому - точки над ё:
Код:
stringList = "-c \"`cat <<EOF\n" + scriptText + "\nEOF`\"";
vs
Код:
QStringList() << "-c" << "cat <<EOF\n + scriptText + \nEOF";
;-)

мож кто-нибудь расскажет про опцию "-с" - встречал только в рекоммендациях к запуску инстоллера нвидийных дров, но, как показывает практика, не нужна, потому в ман не полезу :-[
мож, в ней и дело? хотя врдяли.


Название: Re: QProcess: запуск процесса с помощью "sh -c"
Отправлено: Alex Custov от Август 11, 2010, 02:03
мож кто-нибудь расскажет про опцию "-с" - встречал только в рекоммендациях к запуску инстоллера нвидийных дров, но, как показывает практика, не нужна, потому в ман не полезу :-[

Это должны сделать другие?  :(


Название: Re: QProcess: запуск процесса с помощью "sh -c"
Отправлено: sendevent от Август 11, 2010, 02:41
Это должны сделать другие?  :(
формулировка "а ну, красноглазые задроты, объясните мне БЫСТРО!!!1 <something>" (я утрирую) могла бы заставить подумать, што я считаю, будто кто-то что-то мне должен, и то - только в первые мгновения. использованная же формулировка (к тому же, обратите внимание, в менее контрастной цветовой гамме) - всего лишь
1) попытка донести, что
1.0) мне просто интерсно
1.1) я знаю где получить необходимые сведения и, более того,
1.2) имею возможность реализовать п.1.1 -
данная информация нужна чисто для расширения кругозора, не более;
+
2) (все началось, напомню, с "попытка" - оно имеет отношение и сюда же) немножко заоффтопить тему.
раз уж это не очевидно и приходится объяснять русским по белому - либо мой коммуникабельный косяк, либо не мой.
(ответ: нет, не должны. а чо?)


Название: Re: QProcess: запуск процесса с помощью "sh -c"
Отправлено: Hoblin от Август 11, 2010, 08:03
Всем большое спасибо за помощь! :)

Главным образом помог работающий код Alex Custov - от работоспособного варианта исследовать проблему проще.
Сначала я убедился, что работает - а потом взял и заменил обычный scriptText на `cat <<EOF\nтекст\nEOF`. Программа сразу перестала работать.

Так работает:
Код:
QStringList() << "-c" << scriptText;
Так не работает:
Код:
QStringList() << "-c" << "cat <<EOF\n" + scriptText + "\nEOF";
Итого - упрощаем конструкцию до предела и получаем решение проблемы.

Экранирование кавычек и пробелов с использованием QStringList становится не нужным, можно в параметр запихнуть чистый текст скрипта, что мне и нужно. Проблема решается в несколько простых строчек, как только осознаётся разница между командой и аргументами :)

P.S.
Цитировать
мож кто-нибудь расскажет про опцию "-с"
Она позволяет выполнить команду, указанную следом за "-с". То есть "sh -c command"
Я использую для того, чтобы отдать шеллу скрипт, поступивший в виде строки, не записывая его в файл перед запуском.