sh
Execute shell scripts
TLDR
Start an interactive shell session
Execute a command and then exit
Execute a script
Read and execute commands from stdin
SYNOPSIS
sh [options] [script_file] [arguments...]
sh [options] -c command_string [command_name [arguments...]]
sh [options] -s [arguments...]
PARAMETERS
-c
Reads commands from the provided
-s
Reads commands from standard input. If this option is not specified and no
-i
Makes the shell interactive, meaning it prompts for input and handles job control.
-r
Runs the shell in a restricted mode. This typically disables some functionalities for security reasons, such as changing directories or executing commands with full path names.
-v
Verbose mode. Prints shell input lines as they are read.
-x
Trace mode. Prints commands and their arguments as they are executed, preceded by the value of the PS4 variable.
-e
Exits immediately if a command exits with a non-zero status. Useful for robust scripting.
-u
Treats unset variables as an error. Causes the shell to exit or report an error if it encounters an unset variable during expansion.
DESCRIPTION
The sh command invokes the Bourne shell, a fundamental command language interpreter for Unix-like operating systems. On most modern Linux distributions, sh is typically a symbolic link to another shell, such as Bash (Bourne Again SHell) or Dash (Debian Almquist SHell), providing a POSIX-compliant environment.
As a shell, sh allows users to execute commands, automate tasks through scripts, and manage processes. It reads and executes commands from standard input, a file, or as arguments to its invocation. Its core functionalities include command execution, variable management, I/O redirection, pipeline construction, and control flow constructs like if, for, and while loops.
sh is widely used for system scripting because its syntax forms the basis of the POSIX shell standard, ensuring a high degree of portability across different Unix and Linux systems. While not always the most feature-rich for interactive use compared to shells like Bash or Zsh, its consistency and minimal overhead make it ideal for system startup scripts and portable shell scripts.
CAVEATS
The actual behavior and available features of sh largely depend on which shell it is symbolically linked to on a given system (e.g., bash, dash, or ksh). Script writers should adhere to POSIX shell standards when targeting sh to ensure maximum portability, as relying on shell-specific extensions (e.g., Bashisms) can lead to unexpected behavior or errors on systems where sh points to a different interpreter.
Using the -r (restricted shell) option imposes significant limitations on what commands can be executed and paths can be accessed, primarily for security purposes, which can sometimes be misunderstood or bypassed if not configured carefully.
SYMBOLIC LINK NATURE
On most modern Linux distributions, sh is not a distinct executable but rather a symbolic link to another shell. For example, on Debian and Ubuntu systems, sh typically links to Dash (/bin/sh -> /bin/dash) due to its smaller size and faster startup, making it ideal for system scripts. On other systems, it might link to Bash (/bin/sh -> /bin/bash). You can check where sh points using the command ls -l /bin/sh.
POSIX COMPLIANCE
The primary role of sh in contemporary systems is to provide a shell environment that adheres strictly to the POSIX (Portable Operating System Interface) standard. This compliance ensures that scripts written with #!/bin/sh as their shebang line are highly portable and can run consistently across a wide range of Unix and Linux systems without relying on non-standard features or 'Bashisms'.
HISTORY
The sh command refers to the Bourne shell, which was developed by Stephen Bourne at Bell Labs and first appeared in Version 7 Unix in 1979. It was designed to replace the earlier Thompson shell, introducing more sophisticated features like control flow constructs, functions, and advanced I/O redirection. The Bourne shell quickly became the standard shell on Unix systems due to its powerful scripting capabilities and efficient execution model.
Its syntax and features profoundly influenced the development of subsequent Unix shells, including the Korn Shell (ksh) and the Bourne Again SHell (bash). The Bourne shell's design also formed the foundational basis for the POSIX.1-2001 and POSIX.1-2008 standards for shell command language and utilities, ensuring its legacy as a cornerstone of Unix-like operating systems.