LINUX.ORG.RU

Не получается работать с внешним процессом

 ,


0

3
CL-USER> (defvar *process*)
*PROCESS*
CL-USER> *process*
; Evaluation aborted on #<UNBOUND-VARIABLE *PROCESS* {1007C4B8C3}>.
CL-USER> (let* ((p (sb-ext:run-program "/usr/bin/R" nil
                                       :output :stream
                                       :error :stream
                                       :input :stream
                                       :wait nil))
                (in (sb-ext:process-input p))
                (s (sb-ext:process-output p)))
           (declare (ignorable s in))
           (prog1
               (with-output-to-string (*standard-output*)
                 (loop :for c = (read-char s nil nil)
                       :repeat 10
                       :while (and c
                                   (if (char/= c #\>)
                                       t
                                       (progn
                                         (write-char c)
                                         nil)))
                       :do (write-char c)))
             (setf *process* p)))
""
CL-USER> *process*
#<SB-IMPL::PROCESS :EXITED 2>
CL-USER> (sb-ext:process-alive-p *process*)
NIL
CL-USER> (lisp-implementation-type)
"SBCL"
CL-USER> (lisp-implementation-version)
"1.3.11.debian"

со всякой мелочью типа /bin/ls проблем нет, хотя она также завершается быстро, но зато как положено и с результатом на выводе.

★★★★★

Хех, с тем же самым /usr/bin/sbcl замечательно получается работать.

ados ★★★★★ ()

Если запускать R с ключами -q --no-readline --no-save то замечательно всё работает.

ados ★★★★★ ()
CL-USER> (let* ((p (sb-ext:run-program "/usr/bin/gnuplot" nil
                              :output :stream
                              :error :stream
                              :input :stream
                              :wait nil))
       (in (sb-ext:process-input p))
       (s (sb-ext:process-output p)))
  (declare (ignorable s in))
  (setf *process* p
        *process-output* s
        *process-input* in))
#<SB-SYS:FD-STREAM for "descriptor 74" {10039CDDF3}>
CL-USER> (progn (write-line "pwd" *process-input*)
                (force-output *process-input*))
NIL
CL-USER> (read-line *process-output*)
; Evaluation aborted on NIL.
CL-USER> (read-line *process-output*)
; Evaluation aborted on NIL.
CL-USER> (read-char *process-output*)
; Evaluation aborted on NIL.
CL-USER> (sb-ext:process-alive-p *process*)
T
CL-USER> 

А вот с gnuplot всё как-то сложнее.

ados ★★★★★ ()
Ответ на: комментарий от ados

Хотя вот с этим же процессом:

CL-USER> (progn (write-line "exit" *process-input*)
                (force-output *process-input*))
NIL
CL-USER> (sb-ext:process-alive-p *process*)
NIL
ados ★★★★★ ()
Ответ на: комментарий от ados

; Evaluation aborted on NIL.

Это я не дождавшись вывода жму на (slime-interrupt).

ados ★★★★★ ()
Ответ на: комментарий от ados

А вот с gnuplot всё как-то сложнее.

$ gnuplot 2> /dev/null | wc -l
0

Он в stderr пишет.

mv ★★★★★ ()
Последнее исправление: mv (всего исправлений: 1)
Ответ на: комментарий от mv

Да, точно. Вот жеж гад! А как же приветствия в CLI «gnuplot>»? Как с ним работать если непонятно когда его вывод заканчивается и ожидается ввод команд? Отдельный поток заводить, который постоянно будет ождать текста от gnuplot?

ados ★★★★★ ()
Ответ на: комментарий от ados

Кажется понимаю - вывод от каждой команды завершается вполне стандартно, но у разных команд он может быть разный: у pwd оканчивается символом новой строки, у show variables два символа новой строки подряд, а вот у show all это же концом вывода не будет. Походу нужно писать обработчик для каждой команды - что-то типа реализации протокола. Зато хоть этот «протокол» у гнуплота не такой уж и разнообразный.

ados ★★★★★ ()
Ответ на: комментарий от ados

Как с ним работать если непонятно когда его вывод заканчивается и ожидается ввод команд? Отдельный поток заводить, который постоянно будет ождать текста от gnuplot?

А 'gnuplot /dev/stdin' не работает как надо?

monk ★★★★★ ()
Ответ на: комментарий от monk

А 'gnuplot /dev/stdin' не работает как надо?

Всё так же не могу выловить приветствие «gnuplot>». Как-то программа различает, что-ли, запускает её sbcl а не юзер в терминале и считает что выводить приветствие ненужно.

ados ★★★★★ ()
Ответ на: комментарий от ados

gnuplot /dev/stdin — приветствие не выводит. Вместо этого читает файл, переданный в параметре (/dev/stdin)

monk ★★★★★ ()
Ответ на: комментарий от ados

Как-то программа различает, что-ли, запускает её sbcl а не юзер в терминале и считает что выводить приветствие ненужно.

А в собственную терминальную консоль SBCL для контроля смотрел? Некоторые програмы принципиильно пишут туда минуя swank

У RUN-PROGRAM есть такой параметр как :pty t

antares0 ★★★ ()

Почему кстати не UIOP:RUN-PROGRAM ? Перерабатывать вывод програм с его встроенным UIOP/RUN-PROGRAM:SLURP-INPUT-STREAM немножко проще

antares0 ★★★ ()
Ответ на: комментарий от antares0

Ну вообще всё началось с изучения UIOP/LAUNCH-PROGRAM:LAUNCH-PROGRAM. Возникли проблемы - решил спуститься на уровень ниже.

UIOP:RUN-PROGRAM

А с ним разве можно работать так, чтобы после запуска процесса возвращалось управление в лиспе, а не только после того как процесс выполнит всё что должен и сдохнет?

ados ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.