This is the mail archive of the
mailing list for the Kawa project.
kawa shell concept
- From: Per Bothner <per at bothner dot com>
- To: "kawa at sourceware dot org" <kawa at sourceware dot org>
- Date: Mon, 06 Feb 2012 13:05:01 -0800
- Subject: kawa shell concept
Below is the current state of my ideas for
"Kawa shell" support. Nothing is implemented so far.
Note this integrates with how lazy values are handled. If you
evaluate a (run ...) in a REPL, the output from the command is
"printed" to the repl output. Likewise, you can use the output
whenever a string (or a bytevector) is expected. No need for
special `quotes`. It would help to have an expanded string literal
syntax that supports embedded expressions. (I have a number of goals
for string literals, which makes it non-trivial.)
I'll probably implement something in this vein after 1.12 is released.
I'm uncertain about command names, option names (keywords), macro
vs procedure (probably both), handling Unix's byte vs text ambiguity,
etc etc, but I'm comfortable with the basic concept.
Running programs - Shell-like control of processes
We define a new Scheme process type implemented using a class
ProcessRunner , which extends Lazy<CharSequence>.
The basic Scheme function is something like:
(run keywords... "command-name" "command-options" ...)
This evaluates to a ProcessRunner result.
When output is "displayed" (as in the REPL) it is automatically forced,
and so the command's standard output is copied to the REPL's output.
Output to variable
(define x (run ...))
(define x ::string (run ...)) ;; forced
Input from string
An expression following the keyword parameter in: is evaluated to a
and connected to the standard input of the process:
(run in: "abc" "tr" "a-z" "A-Z") --> "ABC"
(run in: (run "command1") "command2")
path-chars and path-bytes
(path-chars (filepath "/tmp/xxx"))
path-chars returns the contents of the path as a lazy[string].
path-bytes returns the contents of the path as a lazy[bytes].
Input redirection from file
(run in-file: "filename" "command")
is equivalent to:
(run in: (path-bytes (filepath "filename")) "command")
Waits for the process to exit, and returns the exit code.
(process-wait (run ...))
(run shell: #t "ls -l")
In general (on Unix):
(run shell: #t keywords... "command-name" "command-options" ...)
is equivalent to:
(run keywords... "/bin/sh" "-c" "command-name" "command-options" ...)
Other options xs(See Python's subprocess.)
bufsize: size controls buffering.
preexec_fn: procedure Call procedure in the child process just
child is executed. (Unix only.)
close_fds: #f causes all file descriptors except 0, 1 and 2 to be closed
before the child process is executed. (Unix only). Or, on Windows, if
close_fds is true then no handles will be inherited by the child
Note that on Windows, you cannot set close_fds to true and also redirect
the standard handles by setting stdin, stdout or stderr.
cwd: path-or-string the child's current directory will be changed to cwd
before it is executed. Note that this directory is not considered when
searching the executable, so you can’t specify the program's path
env: env-map A mapping that defines the environment variables for
process; these are used instead of inheriting the current process
environment, which is the default behavior.
Encoding: bytes vs chars
Should run be a syntax or function?
Should "command-name" "command-options" be self-quoting symbols or
E.g. (run /bin/ls -l) or (run "/bin/ls" "-l") ?
Perhaps both forms (with different names)?
Perhaps (run /bin/ls ,@(get-ls-options))
Which keyword options?