rash-coreutils
1 How a Rash command is executed
2 Filesystem commands
2.1 pwd
coreutils-pwd
2.2 ls
coreutils-ls
2.3 mkdir
coreutils-mkdir
2.4 rmdir
coreutils-rmdir
2.5 rm
coreutils-rm
2.6 cp
coreutils-cp
2.7 mv
coreutils-mv
2.8 touch
coreutils-touch
2.9 basename
coreutils-basename
2.10 dirname
coreutils-dirname
2.11 realpath
coreutils-realpath
2.12 readlink
coreutils-readlink
2.13 stat
coreutils-stat
2.14 du
coreutils-du
2.15 df
coreutils-df
2.16 mktemp
coreutils-mktemp
3 Text and pipeline commands
3.1 cat
coreutils-cat
3.2 echo
coreutils-echo
3.3 head
coreutils-head
3.4 tail
coreutils-tail
3.5 wc
coreutils-wc
3.6 sort
coreutils-sort
3.7 uniq
coreutils-uniq
3.8 cut
coreutils-cut
3.9 tee
coreutils-tee
3.10 tr
coreutils-tr
4 Environment, time, and executable commands
4.1 which
coreutils-which
4.2 printenv
coreutils-printenv
4.3 env
coreutils-env
4.4 date
coreutils-date
4.5 time
coreutils-time
4.6 raco
coreutils-raco
5 Editor command
5.1 edit
coreutils-edit
current-coreutils-editor
6 Help command
6.1 help
coreutils-help
7 Path selection and Rash expansion
8 Windows paths
9 Capturing and redirecting output
10 Compatibility scope
9.3

rash-coreutils🔗ℹ

Hans Dijkema / hans@dijkewijk.nl

 (require rash-coreutils) package: rash-coreutils

rash-coreutils provides platform-independent Unix-style commands for Rash. The user-facing API is the set of commands that can be written directly in Rash line mode. Most commands are implemented by ordinary Racket procedures, so they do not depend on cmd.exe, PowerShell, or Unix utility executables.

Rash remains responsible for shell syntax such as pipelines, globbing, tilde expansion, variable expansion, and redirection. The command aliases provided by this package preserve those Rash semantics and then dispatch to the internal Racket implementation.

1 How a Rash command is executed🔗ℹ

For a normal command such as

ls -l *.rkt

Rash first processes its line syntax and pipeline semantics. The ls alias then calls dispatch-coreutils-command, which looks up the registered command and invokes coreutils-ls. Arguments that are Racket regular expressions are expanded by the rash-coreutils dispatcher before the internal procedure is called.

This means the shell command is the primary interface, while procedures such as coreutils-ls are the implementation API and are also available to ordinary Racket code.

The option set is deliberately smaller than GNU coreutils. Unsupported options raise an error instead of silently approximating behavior that is not implemented.

2 Filesystem commands🔗ℹ

2.1 pwd🔗ℹ

pwd

Writes the current directory. The command accepts no arguments.

Internally, pwd dispatches to coreutils-pwd.

procedure

(coreutils-pwd)  void?

Writes current-directory using a Rash-friendly textual path.

2.2 ls🔗ℹ

ls

ls -l

ls -a

ls -la

ls *.rkt

ls #px"^info[0-9]+[.]rkt$"

Lists files and directories. -a/all includes hidden names and -l/long writes the portable long form used by this package. Rash performs normal glob expansion. A Racket regular-expression value is an additional rash-coreutils path selector and is matched against names in the current directory.

Internally, ls dispatches to coreutils-ls.

procedure

(coreutils-ls arg ...)  void?

  arg : any/c
Implements the listing after Rash and dispatcher argument handling.

2.3 mkdir🔗ℹ

mkdir work

mkdir -p build/output

Creates one or more directories. -p/parents creates missing parent directories.

Internally, mkdir dispatches to coreutils-mkdir.

procedure

(coreutils-mkdir arg ...)  void?

  arg : any/c
Creates the requested directories.

2.4 rmdir🔗ℹ

rmdir empty-directory

Removes one or more empty directories. No options are currently supported.

Internally, rmdir dispatches to coreutils-rmdir.

procedure

(coreutils-rmdir arg ...)  void?

  arg : any/c
Removes empty directories.

2.5 rm🔗ℹ

rm file.txt

rm -r directory

rm -rf generated

Removes files or links. Directories require -r, -R, or recursive. -f/force suppresses an error for a missing path. The combined forms -rf, -fr, -Rf, and -fR are supported.

Internally, rm dispatches to coreutils-rm.

procedure

(coreutils-rm arg ...)  void?

  arg : any/c
Removes the requested paths.

2.6 cp🔗ℹ

cp source.txt copy.txt

cp -r source-directory copy-directory

Copies exactly one source to one destination. Directory copies require -r, -R, or recursive.

Internally, cp dispatches to coreutils-cp.

procedure

(coreutils-cp arg ...)  void?

  arg : any/c
Copies a file or, in recursive mode, a directory tree.

2.7 mv🔗ℹ

mv old-name.txt new-name.txt

Moves or renames exactly one source path to one destination path.

Internally, mv dispatches to coreutils-mv.

procedure

(coreutils-mv source destination)  void?

  source : any/c
  destination : any/c
Moves or renames a path.

2.8 touch🔗ℹ

touch notes.txt

Creates missing files and updates the modification time of existing files. No options are currently supported.

Internally, touch dispatches to coreutils-touch.

procedure

(coreutils-touch arg ...)  void?

  arg : any/c
Touches one or more files.

2.9 basename🔗ℹ

basename a/b/file.txt

Writes the final component of one path.

Internally, basename dispatches to coreutils-basename.

procedure

(coreutils-basename path)  void?

  path : any/c
Writes the final path component.

2.10 dirname🔗ℹ

dirname a/b/file.txt

Writes the directory portion of one path.

Internally, dirname dispatches to coreutils-dirname.

procedure

(coreutils-dirname path)  void?

  path : any/c
Writes the directory portion of a path.

2.11 realpath🔗ℹ

realpath relative/path

Writes a complete simplified path with filesystem links resolved where the current filesystem supports that resolution.

Internally, realpath dispatches to coreutils-realpath.

procedure

(coreutils-realpath path)  void?

  path : any/c
Writes the complete simplified path.

2.12 readlink🔗ℹ

readlink link-name

Writes the target of one symbolic link and reports an error when the supplied path is not a link.

Internally, readlink dispatches to coreutils-readlink.

procedure

(coreutils-readlink path)  void?

  path : any/c
Writes the resolved symbolic-link target.

2.13 stat🔗ℹ

stat file.txt

stat file.txt directory

Writes portable type, size, and modification information for one or more paths.

Internally, stat dispatches to coreutils-stat.

procedure

(coreutils-stat path ...)  void?

  path : any/c
Writes basic portable path metadata.

2.14 du🔗ℹ

du

du -h directory

Writes the accumulated file size of each requested path. With no path, the current directory is used. -h/human-readable formats the size using binary K, M, and G units. Symbolic links are not followed.

Internally, du dispatches to coreutils-du.

procedure

(coreutils-du arg ...)  void?

  arg : any/c
Calculates recursive file size.

2.15 df🔗ℹ

df

Lists filesystem roots visible to Racket. This portable implementation does not invent platform-specific subprocess fallbacks for total and free capacity.

Internally, df dispatches to coreutils-df.

procedure

(coreutils-df)  void?

Lists filesystem roots.

2.16 mktemp🔗ℹ

mktemp

mktemp -d

mktemp "rash-coreutils-~a"

Creates a unique temporary file and writes its path. -d/directory creates a directory instead. An optional non-option argument is used as the Racket temporary-file template.

Internally, mktemp dispatches to coreutils-mktemp.

procedure

(coreutils-mktemp arg ...)  void?

  arg : any/c
Creates a temporary file or directory and writes its path.

3 Text and pipeline commands🔗ℹ

3.1 cat🔗ℹ

cat file.txt

cat first.txt second.txt

producer | cat

Copies files to standard output. With no file arguments, it copies standard input. This makes the implementation usable in Rash pipelines without special pipeline code.

Internally, cat dispatches to coreutils-cat.

procedure

(coreutils-cat arg ...)  void?

  arg : any/c
Copies file or standard-input bytes to the current output port.

3.2 echo🔗ℹ

echo hello world

Writes its arguments separated by spaces and terminates the result with a newline.

Internally, echo dispatches to coreutils-echo.

procedure

(coreutils-echo arg ...)  void?

  arg : any/c
Writes the textual representation of the arguments.

3.3 head🔗ℹ

head file.txt

head -n 20 file.txt

Writes the first lines of files or standard input. -n/lines selects a non-negative line count; the default is 10. Input is scanned in fixed size byte blocks so memory use does not grow with file size or an individual line length.

Internally, head dispatches to coreutils-head.

procedure

(coreutils-head arg ...)  void?

  arg : any/c
Writes the requested first lines.

3.4 tail🔗ℹ

tail file.txt

tail -n 20 file.txt

Writes the last lines of files or standard input. -n/lines selects a non-negative line count; the default is 10. Seekable files are scanned backwards in fixed-size byte blocks. Input that cannot be scanned backwards is spooled to a temporary file, keeping memory use independent of input size and line length.

Internally, tail dispatches to coreutils-tail.

procedure

(coreutils-tail arg ...)  void?

  arg : any/c
Writes the requested last lines.

3.5 wc🔗ℹ

wc file.txt

wc -l file.txt

wc -w file.txt

wc -c file.txt

Counts lines, words, and bytes. -l selects lines, -w words, and -c/bytes bytes. With no count options all three values are written.

Internally, wc dispatches to coreutils-wc.

procedure

(coreutils-wc arg ...)  void?

  arg : any/c
Counts input using bounded streaming buffers.

3.6 sort🔗ℹ

sort file.txt

sort -r file.txt

sort -n numbers.txt

Sorts input lines. -r/reverse reverses the ordering and -n/numeric-sort uses numeric keys. Large input is divided into bounded in-memory runs and merged through temporary files.

Internally, sort dispatches to coreutils-sort.

procedure

(coreutils-sort arg ...)  void?

  arg : any/c
Sorts lines without retaining the complete input in memory.

3.7 uniq🔗ℹ

uniq sorted.txt

uniq -c sorted.txt

Collapses adjacent duplicate lines. -c/count prefixes each output line with its run count. As with the Unix command, input should already be grouped when non-adjacent equal lines must also be collapsed.

Internally, uniq dispatches to coreutils-uniq.

procedure

(coreutils-uniq arg ...)  void?

  arg : any/c
Collapses adjacent duplicate lines.

3.8 cut🔗ℹ

cut -f 2 data.txt

cut -d ";" -f 3 data.txt

Writes one delimited field from each input line. -f/fields is required and currently accepts one positive field number. -d/delimiter changes the delimiter from the default tab.

Internally, cut dispatches to coreutils-cut.

procedure

(coreutils-cut arg ...)  void?

  arg : any/c
Selects one field from each input line.

3.9 tee🔗ℹ

producer | tee output.txt

producer | tee -a output.txt

Copies standard input to standard output and to each named file. -a/append appends instead of replacing existing file content.

Internally, tee dispatches to coreutils-tee.

procedure

(coreutils-tee arg ...)  void?

  arg : any/c
Copies the current input stream to the current output and files.

3.10 tr🔗ℹ

echo abc | tr a-z A-Z

echo a1b2c3 | tr -d 0-9

echo "a   b" | tr -s " "

Translates characters from standard input. Simple ranges such as a-z, A-Z, and 0-9 are expanded. -d/delete deletes selected characters and -s/squeeze-repeats squeezes repeated selected characters. -ds and -sd are also accepted.

Internally, tr dispatches to coreutils-tr.

procedure

(coreutils-tr arg ...)  void?

  arg : any/c
Translates, deletes, or squeezes characters from the current input port.

4 Environment, time, and executable commands🔗ℹ

4.1 which🔗ℹ

which git

which racket

Finds commands using Racket’s executable search and writes the resolved path.

Internally, which dispatches to coreutils-which.

procedure

(coreutils-which arg ...)  void?

  arg : any/c
Finds one or more executables on PATH.

4.2 printenv🔗ℹ

printenv

printenv PATH

Writes the complete current environment or the values of selected variables. A missing selected variable produces no output.

Internally, printenv dispatches to coreutils-printenv.

procedure

(coreutils-printenv name ...)  void?

  name : any/c
Writes environment-variable values from current-environment-variables.

4.3 env🔗ℹ

env NAME=value printenv NAME

(define x 42)

env ANSWER=(values x) printenv ANSWER

Creates a copy of the current environment, applies leading NAME=value assignments, and either writes the resulting environment or runs the remaining command in it. A parenthesized expression in Rash line mode is ordinary Racket code, so the value following an empty NAME= token can be a Racket value. Registered rash-coreutils commands are tried before an executable on PATH.

Internally, the env Rash alias first preserves Racket expressions in assignment values and then dispatches to coreutils-env.

procedure

(coreutils-env arg ...)  void?

  arg : any/c
Applies temporary environment assignments and optionally runs a command.

4.4 date🔗ℹ

date

date --iso

date --utc --iso

date --tz Europe/Amsterdam --format "yyyy-MM-dd HH:mm:ss"

Writes the current date and time using Gregor. -u/utc selects UTC, -I/iso/iso-8601 selects ISO output, tz ZONE selects a time zone, and format CLDR-PATTERN uses Gregor’s CLDR formatting syntax.

Internally, date dispatches to coreutils-date.

procedure

(coreutils-date arg ...)  void?

  arg : any/c
Writes the current date and time in the requested representation.

4.5 time🔗ℹ

time head -n 100 large.txt

time raco test tests/coreutils.rkt

Executes one registered rash-coreutils command or an executable on PATH and writes timing data to standard error. The portable measurements are elapsed real time, combined cpu time for Racket and completed subprocesses, and Racket gc time. Standard output from the timed command remains usable in pipelines and redirections.

Internally, time dispatches to coreutils-time.

procedure

(coreutils-time command arg ...)  void?

  command : any/c
  arg : any/c
Runs and measures a command.

4.6 raco🔗ℹ

raco setup rash-coreutils

raco pkg show

Runs raco from the active Racket installation. The executable is resolved from that installation before PATH is considered, which avoids accidentally using raco from another Racket installation and also works on Windows when raco.exe is not on PATH.

The Rash command calls coreutils-raco. The exported raco binding is the Rash-facing command binding; ordinary Racket code can call coreutils-raco explicitly.

procedure

(coreutils-raco arg ...)  void?

  arg : any/c
Runs the active installation’s raco executable.

5 Editor command🔗ℹ

5.1 edit🔗ℹ

edit notes.rkt

edit --wait notes.rkt

Opens exactly one file in the editor configured for rash-coreutils. By default, the editor is RackEdit’s rkdt procedure. Without wait, RackEdit opens the editor and the Rash command can continue. With wait, the flag is translated to #:wait? #t, so the command returns only after the editor procedure returns.

Internally, edit dispatches to coreutils-edit. The implementation calls the procedure stored in current-coreutils-editor with the file path and a #:wait? keyword.

procedure

(coreutils-edit arg ...)  void?

  arg : any/c
Parses wait, validates that exactly one file was supplied, and invokes current-coreutils-editor.

A parameter whose default value is rkdt. The configured procedure must accept one file path and the optional keyword #:wait?. A wrapper can be used to select a different editor for a dynamic extent.

(parameterize

    ([current-coreutils-editor

      (λ (filename #:wait? [wait? #f])

        ...)])

  ...)

6 Help command🔗ℹ

6.1 help🔗ℹ

help

help ls

ls --help

help directory-list

With no argument, help writes the registered rash-coreutils command names. For a registered command, it searches Racket documentation using the command’s package-specific index term, for example rash-coreutils-ls. Other terms are passed directly to Racket’s documentation search. Supplying help to a registered command uses the same mechanism.

The help alias calls coreutils-help directly. The normal command dispatcher intercepts help before invoking the command implementation.

procedure

(coreutils-help arg ...)  void?

  arg : any/c
Lists commands or opens Racket documentation for one search term.

7 Path selection and Rash expansion🔗ℹ

Normal shell-style argument expansion remains Rash’s responsibility. The aliases expand back into Rash’s pipeline machinery, preserving globbing, tilde expansion, variable expansion, pipelines, and redirection.

ls *.rkt

ls -l info*

cat info* | wc -l

Racket regular-expression values are an additional rash-coreutils selector. A #rx"" or #px"" value is matched against entry names in the current directory before the internal command procedure is called.

ls #px"^info[0-9]+[.]rkt$"

8 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 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.

9 Capturing and redirecting output🔗ℹ

The internal Racket procedures use normal current ports. Rash can therefore capture, pipe, or redirect command output without command-specific support.

(define git-path { which git |> read-line })

ls &> listing.txt

cat info.rkt &>! copy.rkt

10 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 integration with Racket values are the primary goals.