Ordered from highest precedence to lowest precedence, shell syntax is:
-
grouping, subshell and scheme jobs:
{shell_commands}groups commands. It has no special semantic, its only purpose is group them as a single entity, as parentheses do in math.[shell_commands]executes commands in a subshell.$(scheme_expression optional_args ...)wraps an arbitrary scheme expression in a shell job - in short, a "scheme job" - and executes it.These three syntaxes can be optionally followed by redirections, see 3. and 4. See below for what
shell_commandscan contain. -
command with arguments: that's fundamental,
cmd_name --some-options some-arguments --other-optionsexecutes the command, if found in$PATHIf
cmd_namecontains one or more slashes, as for examplepath/to/some/cmd_name, then it will be only searched in specified directory, without consulting$PATHThe command, and also each argument, can contain zero or more single quotes
"..."and single quotes'...'that are useful to disable some of the steps below. Example:ls path" with "spaces path'<>with"lots$of&special[chars]*\' -
shell glob and substitution, which are performed together i.e. the expansion produced by each one is not parsed again for special characters recognized by the other one.
-
shell glob: command name and its arguments can contain the special sequences
*?and a list of characters surrounded by[]which are expanded to match file system contents. Shell glob is disabled both inside double quotes"..."and inside single quotes'...'and can also be disabled for a single character by preceding it with backslash\ -
substitution: command name and its arguments can contain the special sequences:
$NAMEor${NAME}that expand to the value of the corresponding environment variable, including the special environment variables$0...$9and${NNN}(whereNNNis an unsigned integer) for accessing the n-th command line argument$[shell_commands]or`shell_commands`that expand to the output produced by running theshell_commandsSee below for whatshell_commandscan contain.Substitution works normally inside double quotes
"..."while it is disabled inside single quotes'...'and can also be disabled for a single character by preceding it with backslash\
-
file redirections:
[FD]< FILE,[FD]<> FILE,[FD]> FILEand[FD]>> FILEIfFDis specified, spaces must not be present after it, otherwise itFDwould be parsed as an argument.File redirection is disabled both inside double quotes
"..."and inside single quotes'...'and can also be disabled for a single<or>by preceding it with backslash\ -
file descriptor redirections:
[FD1]<& FD2and[FD1]>& [FD2]whereFD2is an unsigned integer, or -1 which causesFD1to be closed. Again, ifFD1is specified, spaces must not be present after it, otherwise itFD1would be parsed as an argument. Note that command arguments and redirections can be interleaved after the command name in arbitrary order. Bash syntax>& FILEthat redirects both stdout and stderr is not supported, one has to write> FILE 2>&1File descriptor redirection is disabled both inside double quotes
"..."and inside single quotes'...'and can also be disabled for a single<or>by preceding it with backslash\ -
per-command environment variables:
NAME1=VALUE1 [NAME2=VALUE2 ...] CMD_ARGS_AND_REDIRECTIONS. If command is omitted, i.e. onlyNAME=VALUE1 [NAME2=VALUE2 ...]is present, the environment variables are set into the parent job.Per-command environment variables are disabled both inside double quotes
"..."and inside single quotes'...'and can also be disabled for a single=by preceding it with backslash\ -
negation:
! ENVS_CMD_ARGS_AND_REDIRECTIONS. Multiple negations are allowed, as for example!!!ENVS_CMD_ARGS_AND_REDIRECTIONS -
pipeline:
CMD_NOT1 | CMD_NOT2 ...orCMD_NOT1 |& CMD_NOT1 ... -
and:
CMD_PIPE1 && CMD_PIPE2 ...also implements logic short-circuit i.e. terminates at the first failure and returns it -
or:
CMD_AND1 || CMD_AND2 ...also implements logic short-circuit i.e. terminates at the first success and returns it -
list:
CMD_OR1 ; [CMD_OR2 ...]executes the commands sequentially. InsteadCMD_OR1 & [CMD_OR1 ...]starts the first command in background, then immediately proceeds to the remaining commands, if any. Note that newline is treated as;
In this context, shell_commands is the most general syntax i.e. any of the syntaxes listed above.
Also, each argument or redirection file name can be replaced with a shell expression ( ... )
that evaluates to a string, or to a list of strings, or to a closure that accepts zero or one arguments (the job itself)
and returns a string or a list of strings.
Other notable features:
Environment variables and current directory can be different in each job.
When setting an env variable or the current directory, it is stored in a job (by default, the job itself).
Children jobs inherit env variables and current directory from their parent, and can override them.
See also doc/shell/env.md for managing environment variables through scheme functions.
Intentionally missing features:
there are no shell builtins if case func for while that introduce control flow, iteration or functions.
The rationale is: scheme syntax is better suited for such tasks.