中村といいます。 ML でもお世話になってます。
(select-module user) (use expect)をおいて、その下に (define (main argv) ...) を置いた。こうして問題ない?
#!/usr/bin/env gosh ;; $Id: expect.scm,v 1.11 2004/10/13 00:09:14 naka Exp $ (define-module expect (use gauche.process) (use gauche.termios) (export <Expect> spawn send-line expect expect-eof su expect2) ) (select-module expect) (define-class <Expect> () ((pid :init-value -1) fd iport oport readfds (timeout :init-value 5000000.0 ;; nsec :init-keyword :timeout))) (define-method spawn ((obj <Expect>) str) (let* ((args (string-split str #[\s])) (cmd (car args))) (receive (pid fd) (sys-forkpty) (if (= pid 0) (sys-exec cmd args '((0 . 0) (1 . 1) (2 . 2))) ;; child (begin ;; parent (slot-set! obj 'pid pid) (slot-set! obj 'fd fd) (slot-set! obj 'iport (open-input-fd-port fd :buffering :none)) (slot-set! obj 'oport (open-output-fd-port fd :buffering :line)) (slot-set! obj 'readfds (make <sys-fdset>)) (sys-fdset-set! (ref obj 'readfds) fd #t) )) ))) (define-method send-line ((obj <Expect>) str) (format (ref obj 'oport) "~a\n" str)) (define-method timeout-check ((obj <Expect>) . timeout) (let ((fd (ref obj 'fd)) (readfds (ref obj 'readfds)) (timeout (if (null? timeout) (ref obj 'timeout) (car timeout)))) (receive (nfd . dum) (sys-select readfds #f #f timeout) (not (zero? nfd)) ) )) (define-method read-char ((obj <Expect>) . timeout) (let ((iport (ref obj 'iport)) (timeout (if (null? timeout) (ref obj 'timeout) (car timeout)))) (if (timeout-check obj timeout) (read-char iport) (begin (print "timeout error") (exit))) ;;; !!!!!! )) (define-method read-line ((obj <Expect>)) (let loop ((c (read-char obj)) (str "")) (if (or (eof-object? c) (char=? c #\newline)) str (loop (read-char obj) #`",str,c") )) ) (define-method expect2 ((obj <Expect>) regstr . timeout) (let ((regobj (string->regexp regstr)) (timeout (if (null? timeout) (ref obj 'timeout) (car timeout)))) (let loop ((c (read-char obj timeout)) (str "")) (if (eof-object? c) str (if (char=? c #\newline) (begin (print str) (loop (read-char obj timeout) "")) (let* ((str #`",str,c") (pos (rxmatch-start (regobj str)))) (if pos str (loop (read-char obj timeout) str) ))) )) )) (define-method expect ((obj <Expect>) regstr . timeout) (let ((regobj (string->regexp regstr)) (timeout (if (null? timeout) (ref obj 'timeout) (car timeout)))) (let loop ((c (read-char obj timeout)) (str "")) (if (eof-object? c) str (let* ((str #`",str,c") (pos (rxmatch-start (regobj str)))) (if pos (substring str 0 pos) (loop (read-char obj timeout) str) )) )) )) (define-method expect-eof ((obj <Expect>)) (let loop ((c (read-char obj)) (str "")) (if (eof-object? c) str (loop (read-char obj) #`",str,c") )) ) (provide "expect") ;;;;;;;;;;;;;;;;;;;; ;; ;; to show usage ;; (select-module user) (use expect) (define-method su ((obj <Expect>) password rprompt) (spawn obj "su -") (expect obj "assword") (send-line obj password) (expect obj rprompt) ) (define (ssh host passwd cmds . rest) (let ((obj (make <Expect>)) (prmpt (if (null? rest) "\\$ " (car rest)))) (spawn obj #`"slogin ,host") (let ((ans (expect2 obj "(assword|yes)" 5000000.0))) (display ans) (if (char=? #\s (string-ref ans (- (string-length ans) 1))) (begin (send-line obj "yes") (display (expect2 obj "assword" 5000000.0))))) (send-line obj passwd) (display (expect2 obj prmpt 5000000.0)) (for-each (lambda (cmd) (send-line obj cmd) ;;(print "*** " cmd " ***") (display (expect2 obj prmpt 100000.0)) ) cmds) )) (define (usage-example2) (let ((obj (make <Expect>))) (spawn obj "cat") (send-line obj "123456789") (print "*** " (expect2 obj "678") " ***"))) (define (main argv) (usage-example2) ;;(ssh hostname password '("ls" "pwd" "date" "logout") "\\$ ") 0)