2014-04-27 27 views
7

리눅스에서 QProcess을 사용하여 명령을 실행하여 컴퓨터를 다시 시작하고 싶습니다. 내 응용 프로그램에 내 루트 암호를 하드 코딩했습니다. 내가 터미널에 다음을 실행하면Qt에서 복잡한 리눅스 명령어를 실행하는 방법은 무엇입니까?

이 완벽 작동합니다 내가 쉘 스크립트에 명령을 넣어 QProcess를 통해 그것을 호출

echo myPass | sudo -S shutdown -r now 

도 성공 :

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을 사용하여 직접 실행할 수 있습니까? (쉘 스크립트에 넣지 않음).

답변

9

QProcess 설립이 목적을 위해 존재하는 주요 방법 :

void QProcess::setProcessChannelMode(ProcessChannelMode mode)

따라서

void QProcess::setStandardOutputProcess(QProcess * destination)

은 FO llowing의 코드는 하나 개의 통역이나 다른 자신을 제한하지 않고 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 부분을 삭제할 수 있습니다. 종료 프로그램에 대해 setuid 또는 setcap을 설정할 수도 있습니다.

상용 Linux 시스템을 구축 할 때 우리가 일반적으로하는 일은 실행하려고하는 활동에 대해 setuid 또는 setcap을 얻을 수있는 최소 응용 프로그램을 작성한 다음 Linux에서 system(3) 또는 QProcess으로 명시 적으로 호출하는 것입니다. 는 가용성을 제한으로

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

이것은 잘 작동하며 Qt 방식으로 더 일반적이고 더 좋아하기 때문에 좋아합니다. 나는 이것이 무엇인지 모른다 : process2.setProcessChannelMode (QProcess :: ForwardedChannels); – Nejat

+0

@Nejat : 예, 그게 없으면 작동 할 수도 있지만 마지막으로 문제가 생길 때가 있습니다. 그 목적은 하위 프로세스의 출력을 기본 프로세스로 리디렉션하는 것이므로, 귀하의 경우에는 불필요 할 수 있습니다. – lpapp

1

당신은 쉘 스크립트에 명령을 넣고 명령이 sh 또는 bash에 의해 해석되어야한다 |를 포함하고 있기 때문에, 인수로 쉘 스크립트를 QProcess와 sh 또는 bash을 실행해야합니다.

그러나 내 생각에 그것은 다음과 같습니다. 귀하의 루트 암호를 실행 파일에 포함시키는 것이 좋은 해결책이라고 생각하지 않습니다.

+0

이 권장되지 않습니다 다음과 같이 기본적으로,

내가 바로 악의적 인 사용에 대한 액세스, 전체 응용 프로그램에 대한 전체 루트 액세스를 제공 피할 수 있도록 제한하는 작은 응용 프로그램을 작성합니다 주어진 통역사에게. – lpapp

+0

질문을 읽으면 이미 성공적으로 시도해 보았습니다. – Nejat

+0

@LaszloPapp :/bin/sh가없는 Linux 시스템을 알고 있습니까? 문제는 Linux에 관한 것이지 모든 운영 체제에 관한 것이 아닙니다. 명령이 여러 파이프/리디렉터를 사용하여 더 복잡하면 무엇을합니까? 10 QProcess? 쉘 스크립트에서 커맨드를 전용하는 것이 더 유연합니다. 커맨드를 변경하려면 실행 파일을 다시 컴파일 할 필요가 없습니다. – AntiClimacus

2

먼저 비밀번호를 묻지 않도록 sudo을 구성 할 수 있습니다. sudo 그룹의 구성원이하고 /etc/sudoers 파일의 라인

%sudo ALL=NOPASSWD: ALL 

을 가짐으로써 예를 들어. 물론 암호를 묻지 않으면 시스템의 보안이 저하됩니다.

은 (실제로 system(3)/bin/sh -c 분기됩니다) bash(1)는 모든 Posix 쉘, 따라서 /bin/sh처럼 문자열로 -c 인수에 동의 함을 기억 Qt는 대한 귀하의 질문에 대답합니다. 실행이 나쁜 생각 안에 그래서 당신의 루트 암호를 퍼 팅, AntiClimacus answered으로

process.startDetached("/bin/sh", QStringList()<< "-c" 
         << "echo myPass | sudo -S shutdown -r now"); 

을 실행합니다.

+0

Qt는 당신에게 통역사를 제한하지 않는 전용 API를 가지고 있기 때문에 차선책입니다. – lpapp

+0

또한 OP가 이미 이것을 시도한 것 같고 QProcess를 사용하여 비교적 복잡한 명령을 어떻게 직접 실행할 수 있습니까? (쉘 스크립트를 넣지 않음). – lpapp