2010-03-01 2 views
9

RUN-PROGRAM으로 시작하는 프로그램의 출력 스트림을 사용하는 방법을 알아 내려고 노력 중이므로 RUN-PROGRAM으로 시작된 다른 프로그램 (즉, 도덕적이며 아마도 파이프에 상응하는 것)의 입력으로 사용할 수 있습니다. 나는 :INPUT, :OUTPUT:WAIT 키워드 인수의 조합을 사용하여 시도했지만, 에 대한 결과는 지금까지 생산적이었습니다. 모든 팁이 도움이 될 것입니다. 예를 들어 쉘에서 ls | grep lisp과 같은 작업을 수행하려면 어떻게해야합니까? 내 시도Steel Bank Common Lisp에서 입력 및 출력 스트림을 처리하는 방법은 무엇입니까?

하나는 점액 REPL이 실행

(defun piping-test() 
    (let ((grep-process (run-program "/usr/bin/grep" '("lisp") 
            :input :stream 
            :output :stream))) 
    (unwind-protect 
     (with-open-stream (s (process-input grep-process)) 
      (let ((ls-process (run-program "/bin/ls" '() 
             :output s))) 
      (when ls-process 
       (unwind-protect 
        (with-open-stream (o (process-output grep-process)) 
        (loop 
         :for line := (read-line o nil nil) 
         :while line 
         :collect line)) 
       (process-close ls-process))))) 
    (when grep-process (process-close grep-process))))) 

은 꽤 분명 옳은 일이 아니다 그래서 내가 C-c C-c와 을 깰 때까지 걸어 모든 원인,하지만 난 방법을 잘 을하지 않아요 그것을 바꿔서 그것이 옳은 것입니다.

편집 : 모두 RUN-PROGRAM 호출에 :WAIT NIL 추가 또는 grep 만 호출로, 트릭을하지 않습니다. 이 경우 함수가 중단되고 C-c C-c으로 중단되면 SB-UNIX:SELECT이라는 로컬 함수 (FLET을 통해 정의 됨)가 중지되었음을 나타내는 스택 추적을 가져옵니다.

답변

10

나는 Raymond Toy의 답변을 comp.lang.lisp에 받았습니다. 그의 솔루션은 CMUCL 이었지만 CCL의 RUN-PROGRAM은 근본적으로 CMUCL/SBCL에서 나온 클론이기 때문에 밀접하게 관련된 SBCL에서 본질적으로 동일한 RUN-PROGRAM 기능으로 작업했으며 사소한 변경으로 CCL에서도 작동합니다.

(defun piping-test2() 
    (let ((ls-process (run-program "/bin/ls" '() 
           :wait nil 
           :output :stream))) 
    (unwind-protect 
     (with-open-stream (s (process-output ls-process)) 
      (let ((grep-process (run-program "/usr/bin/grep" '("lisp") 
              :input s 
              :output :stream))) 
      (when grep-process 
       (unwind-protect 
        (with-open-stream (o (process-output grep-process)) 
        (loop 
         :for line := (read-line o nil nil) 
         :while line 
         :collect line)) 
       (process-close grep-process))))) 
     (when ls-process (process-close ls-process))))) 

I 또한 :WAIT NIL 생략 실험 : 말하자면

비밀은, 먼저 ls 프로세스를 설정하고 입력으로 grep 프로세스의 출력 스트림을 제공하며,과 같이한다 인수는 RUN-PROGRAM에서 ls으로 전화를 걸었습니다. 물론, 당신은 사용할 수

(with-output-to-string (s) 
     (ccl:run-program "sh" (list "-c" "ls a/directory/somewhere/*.lisp") :output s) 
     s) 

또는

(with-output-to-string (s) 
     (ccl:run-program "sh" (list "-c" "ls /a/directory/somewhere/*.lisp | wc -l") :output s) 
     s) 

또는

(with-output-to-string (s) 
     (ccl:run-program "ssh" (list "[email protected]" "sh -c ls /a/directory/somewhere/on/remote/server/*.lisp | wc -l") :output s) 
     s) 

그리고 :

1

run-program에 인수에 :wait nil을 추가하십시오. grep과 ls가 모두 백그라운드로 실행되고 있어야합니다. 즉, grep 프로세스를 시작하고 그 프로세스가 끝날 때까지 기다린 다음 grep 프로세스를 시작하려고합니다. 아아, 당신이 grep을 끝내기를 기다리고 있기 때문에 결코 그렇게 멀리 가지 않을 것입니다.

1

이와 관련, 그러나 아마 당신의 질문에 발견하지, 당신은 할 수

(format nil "ls ~a" directory) 

다음과 같이 입력 할 수 있습니다.

(with-output-to-string (out) 
     (format t "~%Enter your sudo password:~%") 
     (with-input-from-string (s (read)) 
     (ccl:run-program "ssh" (list *remote* "sudo cat /etc/init.d/nginx") :input s :output out)) 
     out) 
관련 문제