Как выполнить сложные команды linux в Qt? [дубликат]

этот вопрос уже есть ответ здесь:

Я хочу перезагрузить компьютер, выполнив команду в linux с помощью QProcess. У меня есть жестко закодированный пароль root в моем приложении.

когда я запускаю следующее в терминале, он работает идеально:

echo myPass | sudo -S shutdown -r now 

когда я помещаю команду в сценарий оболочки и вызываю ее через QProcess Это также успешно:

QProcess process;
process.startDetached("/bin/sh", QStringList()<< "myScript.sh");

но я не могу запустить его непосредственно переходя к QProcess:

process.startDetached("echo myPass | sudo -S shutdown -r now ");

он будет просто печатать myPass | sudo -S shutdown -r now

как можно запускать такие относительно сложные команды напрямую, используя QProcess. (Не помещая сценарий оболочки).

3 ответов


ключевые методы, которые существуют для этой цели создано в QProcess:

void QProcess::setProcessChannelMode(режим ProcessChannelMode)

и

недействительными чтения qprocess::setStandardOutputProcess(чтения qprocess * назначения)

таким образом, следующий фрагмент кода будет равноценность command1 | command2 не ограничиваясь одним интерпретатором или другой:

QProcess process1
QProcess process2;

process1.setStandardOutputProcess(&process2);

process1.start("echo myPass");
process2.start("sudo -S shutdown -r now");
process2.setProcessChannelMode(QProcess::ForwardedChannels);

// Wait for it to start
if(!process1.waitForStarted())
    return 0;

bool retval = false;
QByteArray buffer;
// To be fair: you only need to wait here for a bit with shutdown,
// but I will still leave the rest here for a generic solution
while ((retval = process2.waitForFinished()));
    buffer.append(process2.readAll());

if (!retval) {
    qDebug() << "Process 2 error:" << process2.errorString();
    return 1;
}

вы могли бы бросить sudo -S часть, потому что вы можете запустить эту небольшую программу как root, а также настроить права. Вы даже можете установить setuid или setcap для программы выключения.

что мы обычно делаем при создании коммерческих систем Linux, чтобы иметь минимальное приложение, которое может получить setuid или setcap для деятельности, которую он пытается сделать, а затем мы вызываем это явно с system(3) или QProcess на Linux. В основном,

Я бы напишите это небольшое приложение, чтобы избежать предоставления полного корневого доступа ко всему приложению, поэтому ограничьте право доступа от вредоносного использования следующим образом:

sudo chmod u+s /path/to/my/application

во-первых, вы можете настроить sudo не запрашивать пароль. Например, будучи членом sudo группа и наличие строки

 %sudo  ALL=NOPASSWD:  ALL

в своем . Конечно, не спрашивать пароль снижает безопасность вашей системы.

чтобы ответить на ваш вопрос о Qt, помните, что Баш(1), как все в POSIX снарядов, поэтому /bin/sh, признать -c аргумент со строкой (на самом деле


вы должны поставить свою команду в shell-скрипт и выполнить sh или bash С QProcess с вашим сценарием оболочки в качестве аргумента, потому что ваша команда содержит |, который должны интерпретируется sh или bash.

однако, это только мое мнение, но: я не думаю, что это хорошее решение, чтобы делать то, что вы делаете, т. е. включать пароль root в исполняемый файл.