2010-03-01 5 views
9

मैं कैसे एक कार्यक्रम के उत्पादन में धारा मैं RUN-PROGRAM के साथ शुरू तो यह किसी अन्य प्रोग्राम के इनपुट के रूप में इस्तेमाल किया जा सकता का उपयोग करने के यह पता लगाने की कोशिश कर रहा हूँ RUN-PROGRAM (अर्थात, नैतिक और शायद शाब्दिक पाइपिंग के समकक्ष) के साथ शुरू कर दिया। मैंने :INPUT, :OUTPUT और :WAIT कीवर्ड तर्कों के कई संयोजनों का उपयोग करने का प्रयास किया है, लेकिन अब तक मैंने पर कुछ भी उत्पादक नहीं किया है। कोई सुझाव उपयोगी होगा; उदाहरण के लिए, मैं खोल से ls | grep lisp जैसे कुछ करने के बारे में कैसे जाउंगा?स्टील बैंक आम लिस्प में इनपुट और आउटपुट स्ट्रीम को कैसे संसाधित करें?

मेरे प्रयासों में से एक

(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 के साथ तोड़ने से एक स्टैक ट्रेस मिलता है जो दर्शाता है कि एक स्थानीय फ़ंक्शन (FLET के माध्यम से परिभाषित किया गया है) जिसे SB-UNIX:SELECT कहा जाता है।

उत्तर

10

मैं comp.lang.lisp पर रेमंड खिलौना से एक काम कर जवाब मिला है। उनका समाधान CMUCL के लिए था, लेकिन यह बारीकी से संबंधित SBCL पर अनिवार्य रूप से समान RUN-PROGRAM समारोह के साथ काम किया है, और मामूली परिवर्तन के साथ यह रूप में अच्छी तरह सीसीएल पर काम करेंगे, क्योंकि सीसीएल के RUN-PROGRAM मूल रूप से CMUCL/SBCL से एक का क्लोन है।

(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))))) 

मैं भी :WAIT NIL को छोड़ते हुए के साथ प्रयोग:

गुप्त, क्योंकि यह थे, पहली ls प्रक्रिया की स्थापना की, और फिर इनपुट के रूप में grep प्रक्रिया के लिए इसके उत्पादन धारा प्रदान करने के लिए इतना की तरह है RUN-PROGRAM से तर्क ls के लिए कॉल करें, और यह भी ठीक काम करता है।

1

:wait nil को run-program पर अपने तर्कों में जोड़ने का प्रयास करें। उसमें आपके grep और ls पृष्ठभूमि में चल रहे दोनों होना चाहिए। जैसा कि, आप grep प्रक्रिया शुरू कर रहे हैं, इसके समाप्त होने की प्रतीक्षा कर रहे हैं, फिर ls शुरू कर रहे हैं जिसे आप grep प्रक्रिया में फ़ीड करना चाहते हैं। हां, चूंकि आप grep को खत्म करने की प्रतीक्षा कर रहे हैं, आप कभी भी इसे प्राप्त नहीं करते हैं।

1

Relatedly, लेकिन शायद अपने प्रश्न का स्थान पर नहीं, तुम कर सकते हो:

(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) 

और, ज़ाहिर है, आप उपयोग कर सकते हैं

(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)