Skip to content
/ lispect Public

A text-terminal automation tool similar to expect(1) using the subset of ISLisp

License

Notifications You must be signed in to change notification settings

hymkor/lispect

Repository files navigation

GoDev

Lispect

  • A text-terminal automation tool similar to expect(1) of UNIX and Linux
  • It runs on Windows 10 and later, and Linux
  • The script is written in the subset of ISLisp (gmnlisp)

example.lsp

$ lispect example.lsp USERNAME@DOMAIN PASSWORD
→ login USERNAME@DOMAIN with ssh and input PASSWORD automatically

(catch 'fail
  (if (< (length ARGV) 2)
    (progn
      (format (error-output) "Usage: ~A ~A USERNAME@DOMAIN PASSWORD~%" EXECUTABLE-NAME PROGRAM-NAME)
      (throw 'fail nil)))

  (let ((account (car ARGV))
        (password (cadr ARGV))
        (sshpid nil))

    (with-handler
      (lambda (c)
        (format (error-output) "ssh is not found~%")
        (throw 'fail nil))
      (setq sshpid (spawn "ssh" account)))

    (expect*
      ("[fingerprint])?"
       (sendln "yes")
       (expect "password:")
       (sendln password))
      ("password:"
       (sendln password))
      (("Connection refused"
        "Could not resolve hostname")
       (throw 'fail nil))
      (30
       (format (error-output) "TIME OUT~%")
       (throw 'fail nil)))

    (expect*
      ("Permission denied"
       (expect "password:")
       (send #\U3)
       (wait sshpid)
       (throw 'fail nil)
       )
      ("$ "))
    (sendln "echo YOU CAN CALL SOME COMMAND HERE")
    (expect "$ ")
    (sendln "exit")
    (wait sshpid)
    )
  )

Install

Download the binary package from Releases and extract the executable.

go install

go install github.com/hymkor/lispect@latest

scoop-installer

scoop install https://raw.githubusercontent.com/hymkor/lispect/master/lispect.json

or

scoop bucket add hymkor https://github.com/hymkor/scoop-bucket
scoop install lispect

Functions and variables

Parameters enclosed in curly braces {...} are optional and can be omitted.

  • (send {'interval MS} "STRING")
    • Send STRING to the terminal
    • Specify the 'interval MS option to make the program wait MS milliseconds before outputting each character
  • (sendln {'interval MS} "STRING")
    • send STRING and Enter-key to the terminal
  • (expect {'timeout SEC} "STRING-0" "STRING-1" ...)
    • Wait until STRINGs are found on the terminal
    • When STRING-n is found on the terminal, it will return n
    • If a timeout occurs after SEC seconds have elapsed, it returns -1
  • (expect* ("STRING-0" COMMANDS-0...) ("STRING-1"...)... (SEC COMMANDS-FOR-TIMEOUT...))
    • When STRING-n is found on the terminal, COMMANDS-n will be executed
    • After SEC seconds have elapsed, COMMANDS-FOR-TIMEOUT will be executed
  • (spawn "COMMANDNAME" "ARG-1" ...)
    • Start the executable file and it returns Process-ID
  • (wait PID)
    • Wait the process specified with PID
  • (getenv "NAME")
    • Get the value of the environment variable NAME
  • (setenv "NAME" "VALUE")
    • Set the value of the environment variable NAME as VALUE
  • ARGV
    • The list of command line arguments
  • PROGRAM-NAME
    • The path of the script
  • EXECUTABLE-NAME
    • The path of the executable of lispect
  • MATCH
    • The matching string in the block of (expect*)
  • (catch TAG-FORM FORM...) and (throw TAG-FORM RESULT-FORM)
  • (with-handler HANDLER FORM...)

Other functions are defined on ISLisp

Comparison with Expect-lua and expect(1)

Expect-lua Lispect expect(1)
Started 2017 2024 1990?
Script Lua (GophaLua) ISLisp (gmnlisp) tcl
Windows 7/8 Supported Not Supported Not Supported
Windows 10/11 Supported Supported Not Supported
Linux Not Supported Supported Supported
Mechanisms ReadConsoleOutputW PseudoConsole PseudoConsole
Read Misses Possible1 Unlikely Never
Stdout Redirection Unavailable Available Available
Status Stable Work in Progress Stable

Technologies used

Footnotes

  1. When the output is too excessive, there might be some dropped data