3 Answers
3

sh calls the program sh as interpreter and the -c flag means execute the following command as interpreted by this program.

In Ubuntu, sh is usually symlinked to /bin/dash, meaning that if you execute a command with sh -c the dash shell will be used to execute the command instead of bash. The shell called with sh depends on the symlink - you can find out with readlink -e $(which sh). You should use sh -c when you want to execute a command specifically with that shell instead of bash.

Read commands from the command_string operand instead of from the
standard input. Special parameter 0 will be set from the command_name
operand and the positional parameters ($1, $2, etc.) set from the
remaining argument operands.

Other details of the sh arugments can be found by running:

$ man sh

An example of using a string as an argument is:

$ sh -c "echo This is a test string"

This is a more detailed sh -c example. It will download a document from Google Drive and open it up for editing on the desktop:

The command following that will be run in that shell session, it will be treated as argument (positional parameter) 0 (ARGV0), and the remaining portion as the argument to that command (ARGV0), starting from 1 (ARGV1, ARGV2, ...).

You can also use typical shell features allowed to run in this kind of session e.g. command separation using ; to use multiple commands, command grouping using {}, spawn another subshell with (), and so on. Usage of these can slightly change the argument definitions/examples mentioned earlier.

Just to note, the features that are specific to interactive shells only (by default), e.g. history expansion, source-ing of ~/.bashrc and /etc/bash.bashrc etc will not be available in this session as it is non-interactive. You can simulate an interactive sessions behavior (almost), by using the -i option:

sh -ic ...

Similarly, the features that are specific to login shells only (by default) e.g. source-ing of ~/.profile (given ~/.bash_profile and ~/.bash_login do not exist) and /etc/profile will not be done as the shell is a non-login shell. You can simulate login-shells behavior using the -l option: