Name

nosh — minimal non-shell script processor

Synopsis

nosh {filename}

Description

nosh reads filename, constructing a sequence of arguments, and then attempts to chain load the program denoted by the first argument, passing it all of the arguments.

nosh is intended for use as a minimal script processor for use in #! lines in executable script files.

It doesn't do argument handling. It doesn't do parsing, parameter substitution, or variables. It doesn't do redirection. It doesn't do syntax. It doesn't do C-style escape sequences.

If you are looking for any of these things, nosh is the wrong tool for the job. Look at execlineb(1) or dash(1).

It does do chain loading, with a wide range of useful built-in chain loading commands available. See exec(1) for details.

File lexing

Arguments are normally separated by one or more whitespace characters. Pairs of quotation mark characters will prevent whitespace from being treated specially, and the quoted sequence of characters, which can include newlines, will form part of one argument, concatenated with whatever quoted or unquoted sequences precede or follow it.

Inside a double-quotation mark delimited sequence of characters: A slash followed by a newline is discarded entirely. A slash followed by any other character is that character. This allows one to provide literal slashes and quotation marks.

In a non-quotation mark delimited sequence of characters: A slash followed by a newline is discarded entirely. A slash followed by any other character is that character. This allows one to provide literal slashes, hashes, and quotation marks. A hash at the start of a sequence is a line comment, that is discarded along with everything that follows it up to and including the end of the line.

Inside a single-quotation mark delimited sequence of characters no characters are discarded or treated specially, except of course the single quotation mark that terminates the sequence.

Example

#!/bin/nosh
echo
This"is"all'one'argument.
This\
"is\
all"\
one\
'argument,'\
too.
These are multiple arguments.
'\' is a single backslash;
"\\" is a single backslash as well;
'#' is a hash; but
# this is a comment, because
unquoted "#" that starts an argument introduces comments.
So because the ''# does not start an argument this is not a comment.

Security

The #! mechanism in Unix is a security disaster. Optional extra arguments (more than one on some operating systems) can be supplied in the trusted script and they cannot be reliably distinguished from arguments supplied by the untrusted user of the script. There is also a race condition caused by the window of opportunity between when a script is executed and when the script interpreter gets around to opening the script file.

nosh avoids the former problem by simply disallowing any optional extra arguments at all, meaning that the script filename is always argument 1. It cannot do anything about the second problem, which has to be solved by the operating system kernel.

Operating systems solve this by providing the fexecve(3) library function. The use of this function results in filename having the form /dev/fd/N or /proc/self/fd/N. nosh detects these circumstances and ensures that open file descriptor N is not leaked into the executed program (if that program is not a built-in command).

Author

Jonathan de Boyne Pollard