You might be interested in an experiment of mine, <a href="https://github.com/tonyg/racket-something/blob/master/src/something/shell.rkt" rel="nofollow">https://github.com/tonyg/racket-something/blob/master/src/so...</a>, which combines an indentation-based reader with a handler for unbound variables to permit fluid interoperation between Racket procedures and external programs.<p>Here's an example (<a href="https://github.com/tonyg/racket-something/blob/master/examples/sh.rkt" rel="nofollow">https://github.com/tonyg/racket-something/blob/master/exampl...</a>):<p><pre><code> #lang something/shell
// Simple demos
ls -la $HOME | grep "^d" | fgrep -v "."
ls -la | wc -l | read-line |> string-split |> car |> string->number |> \
printf "There are ~a lines here." | sed -e "s: are : seem to be :"
(newline)
def ps-output
pipeline
ps -wwwax
preserve-header 1 {: grep "racket" }
space-separated-columns [string->number]
|> csv-expr->table
print ps-output
def message-box text:
whiptail --title "Testing" --ok-button "OK" --msgbox text 8 50
message-box "This is pretty cool."
</code></pre>
`ls`, `grep`, `whiptail` and so on are unbound Racket variables, and the macros forming part of the `something/shell` dialect replace them with calls to the external programs, sorting out the plumbing, pipes and so on. `read-line`, `car`, `string-split`, etc are ordinary Racket functions from the standard libraries.<p>(EDIT): Here's a screencast of an interactive session with the shell. Very simple, but shows some of the basics: <a href="https://asciinema.org/a/83450" rel="nofollow">https://asciinema.org/a/83450</a>
Fun Unix Trivia Time: Touch is supposed to update modified times. That it creates files when they don't exist is only the most common use, not the point of the thing.
This reminds me of my time working with the Scheme Shell scsh!<p>From the readme I don’t quite understand the purpose of lsh, though. Usually, a shell allows you to run programs and manipulate their environment. However, lsh seems to reimplement some commands like find or rm and does not provide operators to manipulate the runtime environment like redirecting output. Maybe you can write in the readme your goal: play with racket, have a shell that accepts racket forms or something different.
It would be nice to see some examples of the syntax, maybe a couple of simple scripts...<p>E.g., the README states that 'cd/' is an alias for '(cd "/")' which seems to imply that one has to wrap every command in '()' and quote every filename... not very practical for a shell!
For the Emacs users, there's eshell - a Shell, implemented in Elisp with the common GNU tooling, but also with the option to hook into regular elisp functions. Pretty cool stuff!
I really like seeing more people use Lisp, and it's neat to see what other people come up with, but I'll stick with Emacs, Slime and occasionally eshell.<p>More often than not it's easiest to just use the Common Lisp functions for creating directories and interacting with the system, but when that doesn't work, I have a function similar to this one in my .sbclrc file:<p>(defun run (cmd)
(with-output-to-string (outs)
(uiop:run-program cmd :output outs)))<p>At work, I've even created a small Common Lisp library for calling our JSON APIs over HTTPS and running commands on our test clusters using SSH. It's all tightly integrated into Emacs, and I can use it do things like open remote files in my local Emacs.
RASH, RAcket SHell library and language: <a href="https://github.com/willghatch/racket-rash" rel="nofollow">https://github.com/willghatch/racket-rash</a><p>Note: I am not the author
See also clojure shell
<a href="https://github.com/dundalek/closh" rel="nofollow">https://github.com/dundalek/closh</a>