From 34058597c826b64ceed786bf964322080e8849ab Mon Sep 17 00:00:00 2001 From: Francois-Rene Rideau <tunes@google.com> Date: Fri, 28 Feb 2014 14:11:45 -0500 Subject: [PATCH] 2.0.0: modify the :OUTPUT and :ERROR-OUTPUT defaults for RUN to T. Have RUN/NIL for the no-output variant, RUN/INTERACTIVE for the interactive variant. --- README | 18 ++++++++++++++---- inferior-shell.asd | 24 ++++++++++++------------ pkgdcl.lisp | 2 +- run.lisp | 29 ++++++++++++++++++++++------- 4 files changed, 49 insertions(+), 24 deletions(-) diff --git a/README b/README index ce231ed..b85a3b5 100644 --- a/README +++ b/README @@ -81,6 +81,7 @@ PRINT-PROCESS-SPEC SPEC &OPTIONAL OUTPUT *CURRENT-HOST-NAMES* a variable, a list of strings, the aliases for the localhost. + You may need to initialize it if the defaults don't suffice. CURRENT-HOST-NAME-P X a function, returns true if X is a string member of *CURRENT-HOST-NAMES* @@ -105,11 +106,12 @@ RUN CMD &KEY ON-ERROR TIME SHOW HOST OUTPUT on which to run the command using ssh if it's not an alias for localhost as recognized by CURRENT-HOST-NAME-P (be sure to have passphraseless login using ssh-agent). - The INPUT, OUTPUT and ERROR-OUTPUT arguments are as for UIOP:RUN-PROGRAM. + The INPUT, OUTPUT and ERROR-OUTPUT arguments are as for UIOP:RUN-PROGRAM, + except that they default to NIL, T, T respectively instead of NIL, NIL, NIL. In particular, OUTPUT is as per UIOP:SLURP-OUTPUT-STREAM one of - NIL (default) for no output (redirect to /dev/null), + NIL for no output (redirect to /dev/null), a stream for itself, - T for the current *standard-output*, + T (default) for the current *standard-output*, :INTERACTIVE for inheriting the parent process's stdout, :LINES for returning one result per line, :STRING for returning the output as one big string, @@ -122,14 +124,22 @@ RUN CMD &KEY ON-ERROR TIME SHOW HOST OUTPUT On Unix, simple commands on localhost are executed directly, but remote commands and pipes are executed by spawning a shell. +RUN/NIL CMD &KEY ON-ERROR TIME SHOW HOST + RUN/NIL is a shorthand for RUN with :INPUT :OUTPUT :ERROR-OUTPUT bound to NIL. + RUN/S CMD &KEY ON-ERROR TIME SHOW HOST - RUN/S is a shorthand for RUN :OUTPUT 'STRING, + RUN/S is a shorthand for RUN with :OUTPUT bound to :STRING, returning as a string what the inferior command sent to its standard output. RUN/SS CMD &KEY ON-ERROR TIME SHOW HOST RUN/S is a shorthand for RUN :OUTPUT :STRING/STRIPPED, just like a shell's `cmd` or $(cmd) would do. +RUN/INTERACTIVE CMD &KEY ON-ERROR TIME SHOW HOST + RUN/INTERACTIVE is a shorthand for RUN with :INPUT :OUTPUT :ERROR-OUTPUT + all boud to :INTERACTIVE, so you may run commands that interact with users, + inheritting the stdin, stdout and stderr of the current process. + RUN/LINES CMD &KEY ON-ERROR TIME SHOW HOST run/lines is a shorthand for RUN :OUTPUT :LINES, returning as a list of one string per line (stripped of line-ending) diff --git a/inferior-shell.asd b/inferior-shell.asd index 5389f9a..4047202 100644 --- a/inferior-shell.asd +++ b/inferior-shell.asd @@ -1,12 +1,13 @@ ;;; -*- Lisp -*- -(defsystem :inferior-shell - :defsystem-depends-on (:asdf #-asdf3 :uiop) - :depends-on ((:version #+asdf3 :asdf #-asdf3 :uiop "3.0.3") - #+sbcl :sb-posix - :alexandria :optima - :fare-utils :fare-quasiquote-extras :fare-mop) +(defsystem "inferior-shell" :description "spawn local or remote processes and shell pipes" + :version "2.0.0" + :defsystem-depends-on (:asdf #-asdf3 "uiop") + :depends-on ((:version #+asdf3 "asdf" #-asdf3 "uiop" "3.0.3") + #+sbcl "sb-posix" + "alexandria" "optima" + "fare-utils" "fare-quasiquote-extras" "fare-mop") :around-compile "asdf-driver:call-with-safe-io-syntax" :components ((:file "pkgdcl") @@ -19,12 +20,11 @@ #+asdf3 (:file "run-sbcl" :depends-on ("process-spec" "macros" "run-generic") :if-feature (:and :sbcl :sb-thread :unix))) - :in-order-to ((test-op (load-op inferior-shell/test))) - :perform (test-op :after (o s) - ;; ASDF2: can't use uiop:symbol-call - (funcall (find-symbol (string :test-suite) :inferior-shell-test)))) + :in-order-to ((test-op (load-op "inferior-shell/test"))) + :perform (test-op :after (o s) ;; symbol-call will only work if loaded with ASDF3 + (symbol-call :inferior-shell-test :test-suite))) -(defsystem :inferior-shell/test - :depends-on (:inferior-shell :hu.dwim.stefil) +(defsystem "inferior-shell/test" + :depends-on ("inferior-shell" "hu.dwim.stefil") :description "testing inferior-shell" :components ((:file "test"))) diff --git a/pkgdcl.lisp b/pkgdcl.lisp index a4143a2..e0246ca 100644 --- a/pkgdcl.lisp +++ b/pkgdcl.lisp @@ -4,7 +4,7 @@ (:mix :fare-utils :uiop :alexandria) (:use :cl :optima :named-readtables :fare-mop) (:export - #:run #:run/s #:run/ss #:run/lines + #:run #:run/nil #:run/s #:run/ss #:run/interactive #:run/lines #:simple-command-line-token #:token-string #:process-spec #:command-spec #:pipe-spec #:or-spec #:and-spec #:progn-spec #:fork-spec diff --git a/run.lisp b/run.lisp index 627df2a..379de18 100644 --- a/run.lisp +++ b/run.lisp @@ -51,29 +51,44 @@ (function (apply 'run-process-spec (funcall host spec) :host nil keys)))) -(defun run (cmd &rest keys - &key time show host (on-error (list "Command ~S failed~@[ on ~A~]" cmd host)) &allow-other-keys) +(defun run/nil (cmd &rest keys + &key time show host + (on-error (list "Command ~S failed~@[ on ~A~]" cmd host)) + &allow-other-keys) + "run command CMD" (labels ((process-time () (if time (time (process-command)) (process-command))) (process-command () (handler-bind ((subprocess-error #'(lambda (c) (error-behavior on-error c)))) - (apply 'run-process-spec cmd - :ignore-error-status nil :host host keys)))) + (apply 'run-process-spec cmd :ignore-error-status nil :host host keys)))) (when show (format *trace-output* "; ~A~%" (print-process-spec cmd))) (process-time))) +(defun run (cmd &rest keys + &key on-error time show host (output t op) (error-output t eop) &allow-other-keys) + "run command CMD" + (apply 'run/nil `(,@(unless op `(:output ,output)) + ,@(unless eop `(:error-output ,erroroutput)) + ,@keys))) + (defun run/s (cmd &rest keys &key on-error time show host) "run command CMD, return its standard output results as a string." (declare (ignore on-error time show host)) - (apply 'run cmd :output 'string keys)) + (apply 'run/nil cmd :output 'string keys)) (defun run/ss (cmd &rest keys &key on-error time show host) "Like run/s, but strips the line ending off the result string; very much like `cmd` or $(cmd) at the shell" (declare (ignore on-error time show host)) - (apply 'run cmd :output :string/stripped keys)) + (apply 'run/nil cmd :output :string/stripped keys)) + +(defun run/interactive (cmd &rest keys &key on-error time show host) + "run command CMD interactively." + (declare (ignore on-error time show host)) + (apply 'run/nil cmd :input :interactive :output :interactive :error-output :interactive keys)) + (defun slurp-stream-string/stripped (input-stream) (stripln (slurp-stream-string input-stream))) @@ -85,4 +100,4 @@ very much like `cmd` or $(cmd) at the shell" (defun run/lines (cmd &rest keys &key on-error time show host) "Like run/s, but return a list of lines rather than one string" (declare (ignore on-error time show host)) - (apply 'run cmd :output :lines keys)) + (apply 'run/nil cmd :output :lines keys)) -- GitLab