bash 명령을 실행하고 싶습니다. Command::new
을 찾았지만 ls ; sleep 1; ls
과 같은 "복잡한"명령을 실행할 수 없습니다. 더욱이이 스크립트를 bash 스크립트에 넣고 실행하더라도 스크립트의 마지막 부분에만 결과가 표시됩니다 (프로세스 문서에 설명되어 있음). 커맨드가 bash에서 할 수있는 것과 같은 방식으로 결과를 출력하자 마자 결과를 얻고 싶습니다.bash 명령을 실행하고 stdout/stderr immediatly 결과를 얻은 다음 stdin을 사용하십시오.
답변
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
,stdout
및stderr
를 포함하는 핸들을 반환하고,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);
감사합니다. 부모 파일 기술자를 사용하고 싶기 때문에'piped()'또는'null()'이 포함 된 줄을 주석 처리했습니다. – x4rkz
'Command'가 빌더 패턴을 따르므로 다음과 같이 구조화하는 것이 더 관용적입니다. https://play.rust-lang.org/?gist=37194d432ecb64c32d5fc5e59937570e&version=stable&backtrace=0 –
@NateMara 사실 처음에는 https : //gist.github.com/2c21ce9e7b919b30cb1444548dc897d9, 그리고 그것은'self' 대신'mut mut'를 취한 것에 대해 상당히 놀랐습니다. 어쨌든 네 말이 맞아, 내 대답을 고쳐 줄게. 고마워. – mcarton
을 "을 할 수 있도록 아이가 부모 파일 디스크립터를 상속 대신 파이프를 설정할 수 있습니다 기본적으로 그 주 또한 입력을 읽는다. " – malbarbo
명령 줄에서 프로그램을 실행하면'./myprog' 프로그램이 매우 자주 프로그램이 명령 행 게임처럼 번호를 물어 보는 등 일부 데이터를 입력 할 때까지 기다리는 것을 의미합니다. Command :: new()를 사용할 때 예를 들어 rust_read_line이라면 즉시 종료됩니다. 아무 것도 입력 할 필요가 없습니다. 명령 줄에서 프로그램을 실행 한 것처럼 실제로 행동하고 싶다는 뜻입니다. – x4rkz