2016-07-24 2 views
0

bash 명령을 실행하고 싶습니다. Command::new을 찾았지만 ls ; sleep 1; ls과 같은 "복잡한"명령을 실행할 수 없습니다. 더욱이이 스크립트를 bash 스크립트에 넣고 실행하더라도 스크립트의 마지막 부분에만 결과가 표시됩니다 (프로세스 문서에 설명되어 있음). 커맨드가 bash에서 할 수있는 것과 같은 방식으로 결과를 출력하자 마자 결과를 얻고 싶습니다.bash 명령을 실행하고 stdout/stderr immediatly 결과를 얻은 다음 stdin을 사용하십시오.

+0

을 "을 할 수 있도록 아이가 부모 파일 디스크립터를 상속 대신 파이프를 설정할 수 있습니다 기본적으로 그 주 또한 입력을 읽는다. " – malbarbo

+0

명령 줄에서 프로그램을 실행하면'./myprog' 프로그램이 매우 자주 프로그램이 명령 행 게임처럼 번호를 물어 보는 등 일부 데이터를 입력 할 때까지 기다리는 것을 의미합니다. Command :: new()를 사용할 때 예를 들어 rust_read_line이라면 즉시 종료됩니다. 아무 것도 입력 할 필요가 없습니다. 명령 줄에서 프로그램을 실행 한 것처럼 실제로 행동하고 싶다는 뜻입니다. – x4rkz

답변

4

Command::new 실제로가는 방법이지만 프로그램을 실행하기위한 것입니다. ls ; sleep 1; ls은 프로그램이 아니며 일부 쉘용 명령어입니다. 당신이 뭔가를 실행하려는 경우, 당신은 당신을 위해 해석 쉘을 요청해야합니다 :

Command::new("/usr/bin/sh").args(&["-c", "ls ; sleep 1; ls"]) 
// your complex command is just an argument for the shell 

출력을 얻으려면 두 가지 방법이 다음과 같습니다 output 방법은 차단

  • 명령의 출력과 종료 상태를 리턴합니다.
  • spawn 방법은 비 차단하고, 그래서 당신은 자녀와 통신 할 수있는 자녀의 과정 stdin, stdoutstderr를 포함하는 핸들을 반환하고, wait 방법은 기다려야가 정상적으로 종료에 대한.

당신은 같은 것을 사용해야합니다 : 당신이 의미하는 무엇을

let child = Command::new("/usr/bin/sh") 
       .args(&["-c", "ls sleep 1 ls"]) 
       .stderr(std::process::Stdio::null()) // don't care about stderr 
       .stdout(std::process::Stdio::piped()) // set up stdout so we can read it 
       .stdin(std::process::Stdio::piped()) // set up stdin so we can write on it 
       .spawn().expect("Could not run the command"); // finally run the command 

write_something_on(child.stdin); 
read(child.stdout); 
+0

감사합니다. 부모 파일 기술자를 사용하고 싶기 때문에'piped()'또는'null()'이 포함 된 줄을 주석 처리했습니다. – x4rkz

+1

'Command'가 빌더 패턴을 따르므로 다음과 같이 구조화하는 것이 더 관용적입니다. https://play.rust-lang.org/?gist=37194d432ecb64c32d5fc5e59937570e&version=stable&backtrace=0 –

+0

@NateMara 사실 처음에는 https : //gist.github.com/2c21ce9e7b919b30cb1444548dc897d9, 그리고 그것은'self' 대신'mut mut'를 취한 것에 대해 상당히 놀랐습니다. 어쨌든 네 말이 맞아, 내 대답을 고쳐 줄게. 고마워. – mcarton