Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a subshell created when I run `sh -c "command"`, a new shell or none of these?

In bash, when I run the following command:

sh -c "command"

is there created a subshell and then the command is executed?

My guess is that the command will run in the current shell, but I'm not sure. This guess come from the fact that I already tested using the following commands:

echo $BASHPID, $BASH_SUBSHELL

and

sh -c "echo $BASHPID, $BASH_SUBSHELL"

and the results are the same. But this could be a little misleading as someone told me because the variables may be substituted before the command is executed. Is this the truth?

like image 871
Radu Rădeanu Avatar asked May 30 '14 09:05

Radu Rădeanu


People also ask

What type of shell is sh?

The Bourne shell ( sh ) is a shell command-line interpreter for computer operating systems. The Bourne shell was the default shell for Version 7 Unix.

What is run sh command?

sh file is nothing but the shell script to install given application or to perform other tasks under Linux and UNIX like operating systems. The easiest way to run . sh shell script in Linux or UNIX is to type the following commands. Open the terminal (your shell prompt) and type the commands. Tutorial details.

What is a subshell command?

A subshell is a separate instance of the command processor -- the shell that gives you the prompt at the console or in an xterm window. Just as your commands are interpreted at the command-line prompt, similarly does a script batch-process a list of commands.

Is it able to run bash scripts on sh shell?

Run Bash Script Using sh Although not that popular anymore, modern Unix-like systems include the interpreter under /bin/sh. The output shows the symbolic link for the sh interpreter. Commonly, Debian and Debian-based systems (such as Ubuntu) link sh to dash, whereas other systems link to bash.


1 Answers

I think that with examples it's possible to understand the situation
(in my case sh is a symbolic link to /bin/dash).
I did this tests for sh:

echo $$ ; sh -c 'echo $$ ; sh -c '"'"'echo $$'"'"' '
16102
7569
7570

Three different PID, three different shell. (If there are different shells, there is not a subshell spawn).


In a similar way for BASH

echo $$ $BASHPID, $BASH_SUBSHELL ; bash -c 'echo $$  $BASHPID $BASH_SUBSHELL  ; bash -c '"'"'echo  $$ $BASHPID $BASH_SUBSHELL '"'"' '
16102 16102, 0
10337 10337 0
10338 10338 0

Three different $BASHPID no different $BASH_SUBSHELL (see note below for differences between $$ and $BASHPID).
If we were in a subshell that do not require to be reinitialized, then $$ and $BASHPID should be different.
In the same way $BASH_SUBSHELL is not incremented, it is always 0. So 2 clues to say again that no new subshell are spawned, we have only new shells.


From man bash (4.2.45(1)-release) I report some pertinent parts about when a subshell is spawned:

  1. Each command in a pipeline is executed as a separate process (i.e., in a subshell).

  2. If a command is terminated by the control operator &, the shell executes the command in the background in a subshell. The shell does not wait for the command to finish, and the return status is 0.

    Commands separated by a ; are executed sequentially; the shell waits for each command to terminate in turn. The return status is the exit status of the last command executed. ...

  3. ( list ) list is executed in a subshell environment
    { list; } list is simply executed in the current shell environment.

  4. A coprocess is a shell command preceded by the coproc reserved word. A coprocess is executed asynchronously in a subshell...

  5. $ Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the current shell, not the subshell.

Notes:

  • BASHPID Expands to the process ID of the current bash process. This differs from $$ under certain circumstances, such as subshells that do not require bash to be re-initialized.
  • BASH_SUBSHELL Incremented by one each time a subshell or subshell environment is spawned. The initial value is 0.

  • For the differences between the use of single quote '' an double quote "" you can see this question. Let we remember only that if you write the commands within double quote"" the variables will be evaluated via parameter expansion from the original shell, if extquote is enabled as it is by default from shopt.(cfr. 4.3.2 The shopt builtin in the Bash Reference Manual)

    *extquote* If set, $'string' and $"string" quoting is performed within ${parameter} expansions enclosed in double quotes. This option is enabled by default.

For further references you may find useful e.g.

  • man bash.
  • The section Shell Expansions of the bash manual.
  • The double quote section or
  • the Parameter Expansion of Shell Command Language as defined in The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition.
like image 73
Hastur Avatar answered Oct 19 '22 20:10

Hastur