Scroll to navigation

rc(1) General Commands Manual rc(1)

NAME

rc - run commands

SYNOPSIS

rc [-c script] [command] [args...]

DESCRIPTION

rc runs the rc shell script at command, with the provided args. If no command is provided, commands are read from the standard input. If the standard input is a terminal, rc starts an interactive shell session.

OPTIONS

-c script

Runs commands from the script argument rather than command. If set, command and args must be omitted.

EXTENDED DESCRIPTION

rc runs shell scripts using a shell command language with various features for scripting command execution. Lines beginning with # are comments and are ignored; # at any unquoted location also causes the remainder of that line to be ignored.

If the shell is started in interactive mode, the file ~/.config/rc/rcstart is sourced on startup (or $XDG_CONFIG_HOME/rc/rcstart, if set).

SIMPLE COMMANDS

Simple commands are formed by forming a list of strings separated by spaces. Double or single quotes may be used to form arguments with spaces or special characters. Commands are terminated by a newline, and '\' may be placed before a newline to cause a command to continue on the subsequent line.

echo hello world
echo "hello world"
echo hello \
	world	# continuation line

Quoted strings which immediately follow each other, without whitespace characters between, are concatenated. Strings with double quotes are subject to variable expansion, i.e. variable references using the $ operators are expanded by the shell. Unquoted characters are interpreted as arguments if they do not include any of the following special characters:

[ ] ( ) { } < > ' " & | ! ; = $ # @ ` \

Escape sequences within quoted strings (either single or double quote) are as follows:

Sequence Character Name
\0 NUL null
\a BEL bell
\f FF form feed
\n LF line feed
\r CR carriage return
\t HT horizontal tab
\v VT vertical tab
\\ \ backslash
\' ' single quote
\" " double quote

GLOBBING

Unquoted strings, when used as arguments to a command, are subject to "globbing". If * appears in an unquoted string, it will be treated as a globbing pattern and expanded to a list of matching files.

The globbing pattern syntax is:

  • ?: matches any single character
  • *: matches any string, including empty string
  • [...]: matches a set of or range of characters
  • [!...]: inverse of [...]
  • \: escapes the following character
  • all other characters match themselves

VARIABLES

To define a variable, use the = operator and provide a value; to reference it, use $:

x="hello world"
echo $x # prints "hello world"

rc supports two types of variables: strings and lists of strings. A list is defined by grouping a list of values, separated by spaces, in parenthesis.

x=(hello world)
echo $x # echo "hello" "world"

The use of a list variable in a command line expands to a series of arguments, rather than a single argument. Conversely, a string variable always expands to a single argument. Thus, it is not necessary to quote variables.

On shell start-up, all environment variables are imported into shell variables and marked as exported.

VARIABLE OPERATORS

$#var

Expands to the length of var, i.e. the number of items in a list or the number of Unicode characters in a string.

x=hello
echo $#x # 5
x=(one two three)
echo $#x # 3

The $# operator may be used on undefined variables without raising an error; it returns 0 in this case.

$"var $'var

If var is a list variable, it will be expanded into a single string consisting of all of its values, separated by spaces or joined without separators, respectively. String variables are expanded normally if accessed with $".

x=(one two three)
echo $x  # echo "one" "two" "three"
echo $"x # echo "one two three"
echo $'x # echo "onetwothree"

$var(n)

Expands to the N-th value of a list variable, or the N-th UTF-8 character of a string variable. Indexed from 1.

$var(x-y)

Expands to a sub-list of a list variable, or a substring of a string variable including the items or characters from index x (inclusive) thru y (exclusive). Either x or y may be omitted to respectively select the first or last item as the lower and upper bounds.

SPECIAL VARIABLES

The following variables are defined by the shell automatically:

Name Value
$* List of arguments
$0, $1, $2, ... String representing the numbered argument*
$pid Process ID of the shell itself
$status Exit status of last command

* Note that $0 is the command name and $1 is the first argument

ARGUMENT EXPANSION

When an argument or value appears unquoted, it is subject to argument expansion. In addition to the operators described by VARIABLE OPERATORS above, the following operators are supported:

`{ script... }
`"string"{ script... }

The script is run in the current shell. The standard output is captured and used as the result of the expansion.

The second form, with the included "string", splits the standard output of script into a list using the characters in "string" as delimiters.

@{ script }
@"string"{ script }

Equivalent to `{}, but a sub-shell is used.

<{ script }
>{ script }

The script is run in the current shell. In the first form, its standard output is captured and written to a named pipe (FIFO). In the second form, its standard input is read from a named pipe. In both cases, the path to the named pipe is used for the expansion.

PIPELINES

Any command may be piped into a another with the | operator.

command | command

The standard output of the first command is connected to the standard input of the second command, then both are executed simultaneously.

command |[fd] command
command |[fd=fd] command

The first file descriptor of the first command is connected to the second file descriptor of the second command, then both commands are executed simultaneously.

If only one file descriptor is provided, the second command's standard input is used.

command && command

The first command is executed. If its $status is zero, the second command is executed.

command || command

The first command is executed. If its $status is non-zero, the second command is executed.

REDIRECTIONS

command > file
command >> file

file is created (or truncated) and command is executed with its standard output connected to this file. If >> is used, the file is appended to rather than truncated if it already exists.

command < file

file is opened for reading and command is executed with its standard input connected to this file.

command >[fd] file

In the first form behaves like >, but the specified file descriptor is redirected to file instead of the standard output or input.

May also be used with >> and <.

command >[fd=]

command is executed with the provided file descriptor closed.

SUB-SCRIPTS

{ script }

The script is executed in the current shell as a single command. May appear as part of a pipeline or include redirects.

IF STATEMENTS

if ( command ) command

The first command is executed. If its status is zero, the second command is executed.

if ( command ) command else command

The first command is executed. If its status is zero, the second command is executed. Otherwise, the third command is executed.

LOOPS

for ( arg ) command
for ( arg in arguments... ) command

Executes command with each value from the list of arguments set to the arg variable one at a time. If arguments is omitted, each value from $* is used from $1.

while ( command ) command

The first command is executed. If its status is zero, the second command is executed. This is repeated until the first command has a non-zero exit status.

FUNCTIONS

fn name command
fn name ( variable list... ) command

A function called name is defined using the provided command. If a command with that name is executed, the provided command will be run in the current shell with $* set to the list of arguments provided to the command.

If a variable list is provided (separated by spaces), each argument will be assigned to a local variable with the given name. Any arguments not provided will leave the corresponding variable unset. $* is unaffected, and may (for instance) be used to access additional arguments beyond the list of named arguments.

fn print_args {
	for (arg) {
		echo $arg
	}
}
print_args hello world
fn write_file(path contents) {
	echo $contents >$path
}
write_file example.txt "hello world"

BUILT-IN COMMANDS

The following commands are built into the shell.

. name args...

Sources the script identified by name, traversing the path if necessary, and executing its contents in the current shell environment. If any arguments are provided, $* is set to those arguments while executing the script.

~ subject patterns...

Tests subject against the provided set of patterns, of which there must be at least one. If any of the patterns match, $status is set to zero, otherwise to one.

The pattern syntax is as follows:

  • ?: matches any single character
  • *: matches any string, including empty string
  • [...]: matches a set of or range of characters
  • [!...]: inverse of [...]
  • \: escapes the following character
  • all other characters match themselves

Globbing is disabled while processing the arguments to a ~ command, so you needn't quote patterns explicitly.

cd directory

Changes the current working directory to directory. If directory is omitted, the cwd is set to $HOME.

break

Causes a for or while loop to terminate immediately.

continue

Causes a for or while loop to continue immediately to the next iteration.

eval script

Parses the script argument and evaluates it in the current shell.

exit status

Exits with the provided exit status, or zero if none is provided.

echo args...

Prints each of its arguments, separated by spaces, and followed by a newline.

read

Reads a line from the standard input and prints it to the standard output. Exits with status code 0 when successful, 127 upon encountering EOF, and a non-zero exit code if an error occured.

Example usage:

while (line=`{read}) {
# ...
}

shift n

Shifts $* over by n values, such that "shift 2" will remove $1 and $2, then reassign $3 to $1 and so on. If n is omitted, 1 is assumed.

unset names...

Unsets the named variables.

AUTHORS

Maintained by Drew Devault <sir@cmpwn.com>.

2025-01-15