221 lines
9.4 KiB
Racket
221 lines
9.4 KiB
Racket
#lang scribble/manual
|
|
|
|
@(require (for-label racket/base
|
|
(only-in rash-coreutils
|
|
coreutils-pwd coreutils-ls coreutils-mkdir coreutils-rmdir
|
|
coreutils-rm coreutils-cp coreutils-mv coreutils-cat
|
|
coreutils-touch coreutils-echo coreutils-which coreutils-head
|
|
coreutils-tail coreutils-wc coreutils-sort coreutils-uniq
|
|
coreutils-cut coreutils-tee coreutils-tr coreutils-basename
|
|
coreutils-dirname coreutils-realpath coreutils-readlink
|
|
coreutils-stat coreutils-du coreutils-df coreutils-mktemp
|
|
coreutils-printenv coreutils-env coreutils-date
|
|
raco
|
|
coreutils-raco)))
|
|
|
|
@title{rash-coreutils}
|
|
@author["Hans Dijkema / hans@dijkewijk.nl"]
|
|
|
|
@defmodule[rash-coreutils]
|
|
|
|
@bold{rash-coreutils} provides platform-independent Unix-style shell commands
|
|
for Rash. The commands are implemented in Racket, so common shell utilities do
|
|
not depend on @tt{cmd.exe}, PowerShell, or Unix executables being installed.
|
|
|
|
Rash remains responsible for shell syntax such as pipelines, globbing, tilde
|
|
expansion, variable expansion, and redirection. @bold{rash-coreutils} supplies
|
|
the commands themselves plus Racket-specific additions such as regular-expression
|
|
path selectors.
|
|
|
|
@section{Commands}
|
|
|
|
The package provides @tt{pwd}, @tt{ls}, @tt{mkdir}, @tt{rmdir}, @tt{rm},
|
|
@tt{cp}, @tt{mv}, @tt{cat}, @tt{touch}, @tt{echo}, @tt{which}, @tt{head},
|
|
@tt{tail}, @tt{wc}, @tt{sort}, @tt{uniq}, @tt{cut}, @tt{tee}, @tt{tr},
|
|
@tt{basename}, @tt{dirname}, @tt{realpath}, @tt{readlink}, @tt{stat}, @tt{du},
|
|
@tt{df}, @tt{mktemp}, @tt{printenv}, @tt{env}, @tt{date}, @tt{raco}, and @tt{help}.
|
|
|
|
The option set is deliberately smaller than GNU coreutils. Unsupported options
|
|
raise an error instead of silently approximating another command's behavior.
|
|
|
|
@section{Racket procedures}
|
|
|
|
Each shell command has an explicitly named Racket procedure. All procedures
|
|
write to the normal current ports so Rash pipeline and redirection semantics
|
|
continue to work.
|
|
|
|
@index["rash-coreutils-pwd"]
|
|
@defproc[(coreutils-pwd) void?]{Writes the current directory.}
|
|
|
|
@index["rash-coreutils-ls"]
|
|
@defproc[(coreutils-ls [arg any/c] ...) void?]{Lists paths. Supports @tt{-a}, @tt{-l}, and their long forms.}
|
|
|
|
@index["rash-coreutils-mkdir"]
|
|
@defproc[(coreutils-mkdir [arg any/c] ...) void?]{Creates directories. Supports @tt{-p}.}
|
|
|
|
@index["rash-coreutils-rmdir"]
|
|
@defproc[(coreutils-rmdir [arg any/c] ...) void?]{Removes empty directories.}
|
|
|
|
@index["rash-coreutils-rm"]
|
|
@defproc[(coreutils-rm [arg any/c] ...) void?]{Removes paths. Supports recursive and force options.}
|
|
|
|
@index["rash-coreutils-cp"]
|
|
@defproc[(coreutils-cp [arg any/c] ...) void?]{Copies a source to a destination. Directory copies require @tt{-r}.}
|
|
|
|
@index["rash-coreutils-mv"]
|
|
@defproc[(coreutils-mv [source any/c] [destination any/c]) void?]{Moves or renames a path.}
|
|
|
|
@index["rash-coreutils-cat"]
|
|
@defproc[(coreutils-cat [arg any/c] ...) void?]{Copies files, or standard input, to standard output.}
|
|
|
|
@index["rash-coreutils-touch"]
|
|
@defproc[(coreutils-touch [arg any/c] ...) void?]{Updates modification times or creates empty files.}
|
|
|
|
@index["rash-coreutils-echo"]
|
|
@defproc[(coreutils-echo [arg any/c] ...) void?]{Writes arguments separated by spaces.}
|
|
|
|
@index["rash-coreutils-which"]
|
|
@defproc[(coreutils-which [arg any/c] ...) void?]{Finds executables using Racket's executable search.}
|
|
|
|
@index["rash-coreutils-head"]
|
|
@defproc[(coreutils-head [arg any/c] ...) void?]{Writes the first lines of input. Supports @tt{-n}.}
|
|
|
|
@index["rash-coreutils-tail"]
|
|
@defproc[(coreutils-tail [arg any/c] ...) void?]{Writes the last lines of input. Supports @tt{-n}.}
|
|
|
|
@index["rash-coreutils-wc"]
|
|
@defproc[(coreutils-wc [arg any/c] ...) void?]{Counts lines, words, and bytes. Supports @tt{-l}, @tt{-w}, and @tt{-c}.}
|
|
|
|
@index["rash-coreutils-sort"]
|
|
@defproc[(coreutils-sort [arg any/c] ...) void?]{Sorts lines. Supports @tt{-r} and @tt{-n}.}
|
|
|
|
@index["rash-coreutils-uniq"]
|
|
@defproc[(coreutils-uniq [arg any/c] ...) void?]{Collapses adjacent duplicate lines. Supports @tt{-c}.}
|
|
|
|
@index["rash-coreutils-cut"]
|
|
@defproc[(coreutils-cut [arg any/c] ...) void?]{Selects one delimited field with @tt{-d} and @tt{-f}.}
|
|
|
|
@index["rash-coreutils-tee"]
|
|
@defproc[(coreutils-tee [arg any/c] ...) void?]{Copies standard input to standard output and files. Supports @tt{-a}.}
|
|
|
|
@index["rash-coreutils-tr"]
|
|
@defproc[(coreutils-tr [arg any/c] ...) void?]{Translates characters from standard input. Character ranges such as @tt{a-z}, @tt{A-Z}, and @tt{0-9} are expanded. @tt{-d} deletes characters and @tt{-s} squeezes repeated characters.}
|
|
|
|
@index["rash-coreutils-basename"]
|
|
@defproc[(coreutils-basename [path any/c]) void?]{Writes the final path component.}
|
|
|
|
@index["rash-coreutils-dirname"]
|
|
@defproc[(coreutils-dirname [path any/c]) void?]{Writes the directory portion of a path.}
|
|
|
|
@index["rash-coreutils-realpath"]
|
|
@defproc[(coreutils-realpath [path any/c]) void?]{Writes a complete simplified path.}
|
|
|
|
@index["rash-coreutils-readlink"]
|
|
@defproc[(coreutils-readlink [path any/c]) void?]{Resolves a symbolic link.}
|
|
|
|
@index["rash-coreutils-stat"]
|
|
@defproc[(coreutils-stat [path any/c] ...) void?]{Writes basic portable path metadata.}
|
|
|
|
@index["rash-coreutils-du"]
|
|
@defproc[(coreutils-du [arg any/c] ...) void?]{Calculates recursive file size. Supports @tt{-h}.}
|
|
|
|
@index["rash-coreutils-df"]
|
|
@defproc[(coreutils-df) void?]{Lists filesystem roots. Racket has no portable API for total and free filesystem capacity, so this initial implementation deliberately does not invent platform-specific subprocess fallbacks.}
|
|
|
|
@index["rash-coreutils-mktemp"]
|
|
@defproc[(coreutils-mktemp [arg any/c] ...) void?]{Creates a temporary file, or a directory with @tt{-d}, and writes its path.}
|
|
|
|
@index["rash-coreutils-printenv"]
|
|
@defproc[(coreutils-printenv [name any/c] ...) void?]{Writes environment variables.}
|
|
|
|
@index["rash-coreutils-env"]
|
|
@defproc[(coreutils-env [arg any/c] ...) void?]{Creates a copied environment, applies leading @tt{NAME=value} assignments, and either writes that environment or runs the remaining command in it. Racket values are converted to environment strings.}
|
|
|
|
The Rash form can mix shell-style assignment names with Racket expressions:
|
|
|
|
@verbatim{
|
|
(define x 42)
|
|
env ANSWER=(values x) printenv ANSWER
|
|
}
|
|
|
|
A parenthesized expression in Rash line mode is ordinary Racket code. Therefore
|
|
the value after an empty @tt{NAME=} token can be a number, symbol, path, string,
|
|
or another printable Racket value.
|
|
|
|
@index["rash-coreutils-date"]
|
|
@defproc[(coreutils-date [arg any/c] ...) void?]{Writes the current date and time using Gregor. Supports @tt{-u}/@tt{--utc}, @tt{-I}/@tt{--iso}, @tt{--tz ZONE}, and @tt{--format CLDR-PATTERN}. The format pattern follows Gregor's CLDR syntax rather than pretending to implement every GNU @tt{date} format escape.}
|
|
|
|
@verbatim{
|
|
date
|
|
date --iso
|
|
date --utc --iso
|
|
date --tz Europe/Amsterdam --format "yyyy-MM-dd HH:mm:ss"
|
|
}
|
|
|
|
@index["rash-coreutils-raco"]
|
|
@defproc[(raco [arg any/c] ...) void?]{Runs @tt{raco} from the current Racket installation. The executable is resolved from the active Racket installation before PATH is considered, so it also works on Windows when @tt{raco.exe} is not on PATH. Arguments may be strings, symbols, paths, numbers, or nested lists. With no arguments, the underlying @tt{raco} program is invoked without a subcommand.}
|
|
|
|
@defproc[(coreutils-raco [arg any/c] ...) void?]{Explicit implementation name for @racket[raco].}
|
|
|
|
@verbatim{
|
|
raco setup rash-coreutils
|
|
raco pkg show
|
|
}
|
|
|
|
The same @racket[raco] binding is a normal Racket procedure, so expression-mode code can use @racket[(raco '(setup rash-coreutils))]. The explicit implementation name @racket[coreutils-raco] is also exported.
|
|
|
|
@section{Path selection}
|
|
|
|
Shell-style argument expansion remains Rash's responsibility. The aliases expand
|
|
back into Rash's @tt{=unix-pipe=} operator, preserving Rash globbing, tilde
|
|
expansion, and @tt{$} expansion.
|
|
|
|
@verbatim{
|
|
ls *.rkt
|
|
ls -l info*
|
|
cat info*
|
|
}
|
|
|
|
Regular-expression values are an additional @bold{rash-coreutils} selector. A
|
|
@racket[#rx""] or @racket[#px""] value is matched against entry names in the
|
|
current directory.
|
|
|
|
@verbatim{
|
|
ls #px"^info[0-9]+[.]rkt$"
|
|
}
|
|
|
|
|
|
@section{Windows paths}
|
|
|
|
On Windows, commands that write path names use forward slashes in their textual output. Rash treats backslashes as escape characters in line mode, so a printed path such as @tt{C:/Users/name/AppData/Local/Temp/file} can be copied directly into another Rash command. Racket path values themselves remain native and can be passed directly to a command through a Racket expression.
|
|
|
|
@section{Help}
|
|
|
|
@tt{help} uses Racket's documentation search through @tt{raco docs}. Registered
|
|
commands use package-specific index terms such as @tt{rash-coreutils-ls}.
|
|
|
|
@verbatim{
|
|
help
|
|
help ls
|
|
ls --help
|
|
help directory-list
|
|
}
|
|
|
|
@section{Capturing and redirecting output}
|
|
|
|
Commands use normal ports. Rash can therefore capture or redirect them without
|
|
special support in this package.
|
|
|
|
@verbatim{
|
|
(define git-path { which git |> read-line })
|
|
ls &> listing.txt
|
|
cat info.rkt &>! copy.rkt
|
|
}
|
|
|
|
@section{Compatibility scope}
|
|
|
|
The command names and common options follow Unix conventions, but this package
|
|
does not claim complete GNU coreutils compatibility. Platform-independent
|
|
behavior, predictable Rash scripting, and useful integration with Racket values
|
|
are the primary goals.
|