The cmd Reference Manual

Table of Contents

Next: , Previous: , Up: (dir)   [Contents][Index]

The cmd Reference Manual

This is the cmd Reference Manual, version 0.0.1, generated automatically by Declt version 3.0 "Montgomery Scott" on Mon Apr 19 15:41:35 2021 GMT+0.


Next: , Previous: , Up: Top   [Contents][Index]

1 Introduction

cmd

A utility for running external programs, built on UIOP.

Cmd is designed to:

  1. Be natural to use.
  2. Protect against shell interpolation.
  3. Be usable from multi-threaded programs.
  4. Support Windows.

Argument handling

Arguments to cmd are never passed to a shell for interpretation.

Arguments are handled as follows:

  1. A string is tokenized (using cl-shlex) and added to the list of arguments.

    (cmd "ls -al")
    ≡ (uiop:run-program '("ls" "-al"))
    
    (cmd "echo 'hello world'")
    ≡ (uiop:run-program '("echo" "hello world"))
    
  2. A list of strings is added directly to the list of arguments (not tokenized). (Putting a string in a list is “escaping” it.)

    (cmd "bash -c 'exit 1'")
    ≡ (cmd "bash -c" '("exit 1"))
    
  3. A literal keyword, along with the next value, is passed through as a keyword argument to UIOP.

    (cmd "bash -c 'exit 1'" :ignore-error-status t)
    ≡ (cmd :ignore-error-status t "bash -c 'exit 1'")
    ≡ (cmd "bash -c" :ignore-error-status t '("exit 1"))
    ≡ (uiop:run-program '("bash" "-c" "exit 1") :ignore-error-status t)
    

    Note that unlike normal Lisp functions, keyword arguments can appear anywhere, not just at the end.

  4. Any other string, integer, or pathname is directly added to the list of arguments. (It is an error if a pathname begins with -.)

The external program’s working directory

Cmd is designed with multi-threaded programs in mind. It always runs programs with their working directory relative to *default-pathname-defaults*. This is because the OS-level working directory a program, on both Windows and Unix, is the working directory of the entire process, not the individual thread, and changing it changes it for all threads.

You can also specify the directory for a particular command with the keyword argument :in:

(cmd "ls" :in #p"/")
(cmd :in #p"/" "ls")
=> /bin /home /tmp /usr ...

Entry points

The cmd package offers several entry points:

Redirection

Redirection is accomplished via keyword arguments. These should be self-explanatory to anyone who has used a shell.

(cmd "echo 'hello world'" :> #p"hello.txt")
(cmd "cat" #p"hello.txt")
=> hello world
;; Append
(cmd "echo 'goodbye world'" :>> #p"hello.txt")
(cmd "cat" #p"hello.txt")
=> hello world
   goodbye world
(cmd "tar cf -" #p"hello.txt" :> #p"hello.tar")
(cmd "rm" #p"hello.txt")
(cmd "tar xf" #p"hello.tar")
(cmd "cat" #p"hello.txt")
=> hello world
   goodbye world

Supported directions are:

Controlling cmd with hooks

There are two hooks you can use to control cmd. These are exported from the cmd/hooks package (so you can :use :cmd without having to worry about them.) Both hooks expect a list of functions of one argument.

The hook *message-hook* is called with the external program and its arguments, quoted as a shell command line. This can be useful for logging commands as they are run.

The hook *proc-hook* is called with the process object (as returned by uiop:launch-program). This can be useful if you want to be able to track what is being run in a particular dynamic extent.

Windows

On Windows only, the first argument (the program name) has .exe appended to it automatically if it doesn’t already have a file extension.

Efficiency

While cmd does not use a shell to interpret its arguments, it does still have to run a shell (sh on Unix, cmd.exe on Windows) in order to change the working directory of the program.

How inefficient this is depends on what your distribution uses as a shell; it is faster when sh is, say, dash, than when it is bash.

Recent versions of GNU env support a -C switch to do this directly. When that is supported (support is detected dynamically) then env -C is used in place of a shell and overhead is negligible.

Past

Cmd is a spinoff of Overlord, a Common Lisp build system, and was inspired by the cmd function in Shake, a Haskell build system.

Future

I plan to support at least inline redirection (e.g. (cmd "sth file > other-file")) and pipelines.


Next: , Previous: , Up: Top   [Contents][Index]

2 Systems

The main system appears first, followed by any subsystem dependency.


Next: , Previous: , Up: Systems   [Contents][Index]

2.1 cmd

Author

Paul M. Rodriguez <pmr@ruricolist.com>

License

MIT

Description

A utility for running external programs

Version

0.0.1

Dependency

cmd/cmd (system)

Source

cmd.asd (file)


Next: , Previous: , Up: Systems   [Contents][Index]

2.2 cmd/cmd

Author

Paul M. Rodriguez <pmr@ruricolist.com>

License

MIT

Dependencies
Source

cmd.asd (file)

Component

file-type.lisp (file)


Previous: , Up: Systems   [Contents][Index]

2.3 cmd/hooks

Author

Paul M. Rodriguez <pmr@ruricolist.com>

License

MIT

Dependencies
Source

cmd.asd (file)

Component

file-type.lisp (file)


Next: , Previous: , Up: Top   [Contents][Index]

3 Files

Files are sorted by type and then listed depth-first from the systems components trees.


Previous: , Up: Files   [Contents][Index]

3.1 Lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.1 cmd.asd

Location

cmd.asd

Systems

Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.2 cmd/cmd/file-type.lisp

Parent

cmd/cmd (system)

Location

cmd.lisp

Packages

cmd/cmd

Exported Definitions
Internal Definitions

Previous: , Up: Lisp files   [Contents][Index]

3.1.3 cmd/hooks/file-type.lisp

Parent

cmd/hooks (system)

Location

hooks.lisp

Packages

cmd/hooks

Exported Definitions

Next: , Previous: , Up: Top   [Contents][Index]

4 Packages

Packages are listed by definition order.


Next: , Previous: , Up: Packages   [Contents][Index]

4.1 cmd/cmd

Source

file-type.lisp (file)

Nickname

cmd

Use List
Exported Definitions
Internal Definitions

Previous: , Up: Packages   [Contents][Index]

4.2 cmd/hooks

Source

file-type.lisp (file)

Use List
Used By List

cmd/cmd

Exported Definitions

Next: , Previous: , Up: Top   [Contents][Index]

5 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


Next: , Previous: , Up: Definitions   [Contents][Index]

5.1 Exported definitions


Next: , Previous: , Up: Exported definitions   [Contents][Index]

5.1.1 Special variables

Special Variable: *message-hook*
Package

cmd/hooks

Source

file-type.lisp (file)

Special Variable: *proc-hook*
Package

cmd/hooks

Source

file-type.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

5.1.2 Macros

Macro: with-cmd-dir DIR &body BODY
Package

cmd/cmd

Source

file-type.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

5.1.3 Compiler macros

Compiler Macro: $cmd CMD &rest ARGS
Package

cmd/cmd

Source

file-type.lisp (file)

Compiler Macro: cmd CMD &rest ARGS
Package

cmd/cmd

Source

file-type.lisp (file)

Compiler Macro: cmd! CMD &rest ARGS
Package

cmd/cmd

Source

file-type.lisp (file)

Compiler Macro: cmd& CMD &rest ARGS
Package

cmd/cmd

Source

file-type.lisp (file)

Compiler Macro: cmd? CMD &rest ARGS
Package

cmd/cmd

Source

file-type.lisp (file)


Previous: , Up: Exported definitions   [Contents][Index]

5.1.4 Functions

Function: $cmd CMD &rest ARGS

Return the results of CMD as a string, stripping any trailing newlines, like $(cmd) would in a shell.

By default stderr is discarded.

Package

cmd/cmd

Source

file-type.lisp (file)

Function: cmd CMD &rest ARGS

Run a program.

CMD should be a string naming a program. This command will be run with
its current directory set to the value of the current directory in a
thread-safe manner.

The current directory is based on ‘*default-pathname-defaults*’, not on the OS-level working directory, as the OS-level directory is useless for multi-threaded programs.

A list of strings or pathnames is added to the list of arguments.

A string in ARGS is split into a list of tokens using shell-style
tokenization rules. (To protect a string with spaces, either add
quotation marks, or enclose it in a singleton list.)

A pathname in ARGS is translated to a native namestring and passed as
an argument to the command. The native namestring is not permitted to
start with a dash.

A property list is treated as a list of keyword arguments to
‘uiop:run-program’. Certain keywords are treated as abbreviations:
e.g. ‘:>’ is an abbreviation for ‘:output’. Abbreviations can be
compound: e.g. ‘:>>’ affects both ‘:output’ and ‘:if-exists’.

By default, standard output is sent to ‘*standard-output*’, and error
output is sent to ‘*message-stream*’.

On Windows, the .exe suffix may be omitted from the name of the
executable.

Package

cmd/cmd

Source

file-type.lisp (file)

Function: cmd! CMD &rest ARGS

Run CMD purely for its side effects, discarding all output and returning nothing.

Package

cmd/cmd

Source

file-type.lisp (file)

Function: cmd& CMD &rest ARGS

Like ‘cmd’, but run asynchronously and return a handle on the process (as from ‘launch-program’).

Package

cmd/cmd

Source

file-type.lisp (file)

Function: cmd? CMD &rest ARGS

Run a program, returning T if it passed, nil otherwise. By default the output is discarded.

Package

cmd/cmd

Source

file-type.lisp (file)


Previous: , Up: Definitions   [Contents][Index]

5.2 Internal definitions


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.1 Special variables

Special Variable: *can-use-env-c*
Package

cmd/cmd

Source

file-type.lisp (file)

Special Variable: *keyword-abbrevs*
Package

cmd/cmd

Source

file-type.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.2 Symbol macros

Symbol Macro: +env+
Package

cmd/cmd

Source

file-type.lisp (file)

Expansion

cmd/cmd::*storage-for-deflex-var-+env+*

Symbol Macro: +kill+
Package

cmd/cmd

Source

file-type.lisp (file)

Expansion

cmd/cmd::*storage-for-deflex-var-+kill+*

Symbol Macro: +ps+
Package

cmd/cmd

Source

file-type.lisp (file)

Expansion

cmd/cmd::*storage-for-deflex-var-+ps+*

Symbol Macro: +pwd+
Package

cmd/cmd

Source

file-type.lisp (file)

Expansion

cmd/cmd::*storage-for-deflex-var-+pwd+*

Symbol Macro: +sh+
Package

cmd/cmd

Source

file-type.lisp (file)

Expansion

cmd/cmd::*storage-for-deflex-var-+sh+*

Symbol Macro: +tr+
Package

cmd/cmd

Source

file-type.lisp (file)

Expansion

cmd/cmd::*storage-for-deflex-var-+tr+*


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.3 Macros

Macro: define-cmd-variant NAME LAMBDA-LIST &body BODY
Package

cmd/cmd

Source

file-type.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.4 Functions

Function: await PROC &key IGNORE-ERROR-STATUS TOKENS

Wait for PROC to finish.

Package

cmd/cmd

Source

file-type.lisp (file)

Function: call/cmd-dir FN DIR
Package

cmd/cmd

Source

file-type.lisp (file)

Function: can-use-env-c? ()
Package

cmd/cmd

Source

file-type.lisp (file)

Function: current-dir ()
Package

cmd/cmd

Source

file-type.lisp (file)

Function: exe-string P
Package

cmd/cmd

Source

file-type.lisp (file)

Function: expand-keyword-abbrevs ARGS
Package

cmd/cmd

Source

file-type.lisp (file)

Function: kill-process PROCESS &key URGENT

Terminate PROCESS and all its descendants.
On Unix, sends a TERM signal by default, or a KILL signal if URGENT.

Package

cmd/cmd

Source

file-type.lisp (file)

Function: launch-program-in-dir DIR TOKENS &rest ARGS &key &allow-other-keys
Package

cmd/cmd

Source

file-type.lisp (file)

Function: launch-program-in-dir* TOKENS &rest ARGS

Run a program (with uiop:run-program) in the current base directory.

Package

cmd/cmd

Source

file-type.lisp (file)

Function: parse-cmd-args ARGS
Package

cmd/cmd

Source

file-type.lisp (file)

Function: simplify-cmd-args ARGS
Package

cmd/cmd

Source

file-type.lisp (file)

Function: split-cmd CMD
Package

cmd/cmd

Source

file-type.lisp (file)

Function: stringify-pathname ARG
Package

cmd/cmd

Source

file-type.lisp (file)

Function: update-can-use-env-c ()
Package

cmd/cmd

Source

file-type.lisp (file)

Function: wrap-with-dir DIR TOKENS

Wrap TOKENS with the necessary code to run the process in DIR.

The OS-level current directory is per-process, not per thread. Using ‘chdir’ could lead to race conditions. Instead, we arrange for the new process to change its own working directory.

Package

cmd/cmd

Source

file-type.lisp (file)


Previous: , Up: Internal definitions   [Contents][Index]

5.2.5 Types

Type: plist ()
Package

cmd/cmd

Source

file-type.lisp (file)


Previous: , Up: Top   [Contents][Index]

Appendix A Indexes


Next: , Previous: , Up: Indexes   [Contents][Index]

A.1 Concepts

Jump to:   C   F   L  
Index Entry  Section

C
cmd.asd: The cmd․asd file
cmd/cmd/file-type.lisp: The cmd/cmd/file-type․lisp file
cmd/hooks/file-type.lisp: The cmd/hooks/file-type․lisp file

F
File, Lisp, cmd.asd: The cmd․asd file
File, Lisp, cmd/cmd/file-type.lisp: The cmd/cmd/file-type․lisp file
File, Lisp, cmd/hooks/file-type.lisp: The cmd/hooks/file-type․lisp file

L
Lisp File, cmd.asd: The cmd․asd file
Lisp File, cmd/cmd/file-type.lisp: The cmd/cmd/file-type․lisp file
Lisp File, cmd/hooks/file-type.lisp: The cmd/hooks/file-type․lisp file

Jump to:   C   F   L  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.2 Functions

Jump to:   $  
A   C   D   E   F   K   L   M   P   S   U   W  
Index Entry  Section

$
$cmd: Exported compiler macros
$cmd: Exported functions

A
await: Internal functions

C
call/cmd-dir: Internal functions
can-use-env-c?: Internal functions
cmd: Exported compiler macros
cmd: Exported functions
cmd!: Exported compiler macros
cmd!: Exported functions
cmd&: Exported compiler macros
cmd&: Exported functions
cmd?: Exported compiler macros
cmd?: Exported functions
Compiler Macro, $cmd: Exported compiler macros
Compiler Macro, cmd: Exported compiler macros
Compiler Macro, cmd!: Exported compiler macros
Compiler Macro, cmd&: Exported compiler macros
Compiler Macro, cmd?: Exported compiler macros
current-dir: Internal functions

D
define-cmd-variant: Internal macros

E
exe-string: Internal functions
expand-keyword-abbrevs: Internal functions

F
Function, $cmd: Exported functions
Function, await: Internal functions
Function, call/cmd-dir: Internal functions
Function, can-use-env-c?: Internal functions
Function, cmd: Exported functions
Function, cmd!: Exported functions
Function, cmd&: Exported functions
Function, cmd?: Exported functions
Function, current-dir: Internal functions
Function, exe-string: Internal functions
Function, expand-keyword-abbrevs: Internal functions
Function, kill-process: Internal functions
Function, launch-program-in-dir: Internal functions
Function, launch-program-in-dir*: Internal functions
Function, parse-cmd-args: Internal functions
Function, simplify-cmd-args: Internal functions
Function, split-cmd: Internal functions
Function, stringify-pathname: Internal functions
Function, update-can-use-env-c: Internal functions
Function, wrap-with-dir: Internal functions

K
kill-process: Internal functions

L
launch-program-in-dir: Internal functions
launch-program-in-dir*: Internal functions

M
Macro, define-cmd-variant: Internal macros
Macro, with-cmd-dir: Exported macros

P
parse-cmd-args: Internal functions

S
simplify-cmd-args: Internal functions
split-cmd: Internal functions
stringify-pathname: Internal functions

U
update-can-use-env-c: Internal functions

W
with-cmd-dir: Exported macros
wrap-with-dir: Internal functions

Jump to:   $  
A   C   D   E   F   K   L   M   P   S   U   W  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.3 Variables

Jump to:   *   +  
S  
Index Entry  Section

*
*can-use-env-c*: Internal special variables
*keyword-abbrevs*: Internal special variables
*message-hook*: Exported special variables
*proc-hook*: Exported special variables

+
+env+: Internal symbol macros
+kill+: Internal symbol macros
+ps+: Internal symbol macros
+pwd+: Internal symbol macros
+sh+: Internal symbol macros
+tr+: Internal symbol macros

S
Special Variable, *can-use-env-c*: Internal special variables
Special Variable, *keyword-abbrevs*: Internal special variables
Special Variable, *message-hook*: Exported special variables
Special Variable, *proc-hook*: Exported special variables
Symbol Macro, +env+: Internal symbol macros
Symbol Macro, +kill+: Internal symbol macros
Symbol Macro, +ps+: Internal symbol macros
Symbol Macro, +pwd+: Internal symbol macros
Symbol Macro, +sh+: Internal symbol macros
Symbol Macro, +tr+: Internal symbol macros

Jump to:   *   +  
S  

Previous: , Up: Indexes   [Contents][Index]

A.4 Data types

Jump to:   C   P   S   T  
Index Entry  Section

C
cmd: The cmd system
cmd/cmd: The cmd/cmd system
cmd/cmd: The cmd/cmd package
cmd/hooks: The cmd/hooks system
cmd/hooks: The cmd/hooks package

P
Package, cmd/cmd: The cmd/cmd package
Package, cmd/hooks: The cmd/hooks package
plist: Internal types

S
System, cmd: The cmd system
System, cmd/cmd: The cmd/cmd system
System, cmd/hooks: The cmd/hooks system

T
Type, plist: Internal types

Jump to:   C   P   S   T