Russian Qt Forum
Май 02, 2024, 15:46 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QProcess: запуск процесса с помощью "sh -c"  (Прочитано 6294 раз)
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 моего сообщения. Копирую, вставляю в консоль - работает.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Август 10, 2010, 16:42 »

В QProcess в качестве комманды передавай sh, а остальное передавай как параметры в QStringList.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Hoblin
Гость
« Ответ #2 : Август 10, 2010, 17:12 »

А разве есть разница?

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

Сообщений: 2063


Просмотр профиля
« Ответ #3 : Август 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();
 
Записан
sendevent
Гость
« Ответ #4 : Август 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";
;-)

мож кто-нибудь расскажет про опцию "-с" - встречал только в рекоммендациях к запуску инстоллера нвидийных дров, но, как показывает практика, не нужна, потому в ман не полезу Обеспокоенный
мож, в ней и дело? хотя врдяли.
« Последнее редактирование: Август 11, 2010, 01:59 от sendevent » Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #5 : Август 11, 2010, 02:03 »

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

Это должны сделать другие?  Грустный
Записан
sendevent
Гость
« Ответ #6 : Август 11, 2010, 02:41 »

Это должны сделать другие?  Грустный
формулировка "а ну, красноглазые задроты, объясните мне БЫСТРО!!!1 <something>" (я утрирую) могла бы заставить подумать, што я считаю, будто кто-то что-то мне должен, и то - только в первые мгновения. использованная же формулировка (к тому же, обратите внимание, в менее контрастной цветовой гамме) - всего лишь
1) попытка донести, что
1.0) мне просто интерсно
1.1) я знаю где получить необходимые сведения и, более того,
1.2) имею возможность реализовать п.1.1 -
данная информация нужна чисто для расширения кругозора, не более;
+
2) (все началось, напомню, с "попытка" - оно имеет отношение и сюда же) немножко заоффтопить тему.
раз уж это не очевидно и приходится объяснять русским по белому - либо мой коммуникабельный косяк, либо не мой.
(ответ: нет, не должны. а чо?)
Записан
Hoblin
Гость
« Ответ #7 : Август 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"
Я использую для того, чтобы отдать шеллу скрипт, поступивший в виде строки, не записывая его в файл перед запуском.
« Последнее редактирование: Август 11, 2010, 08:07 от Hoblin » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.082 секунд. Запросов: 23.