Home > Net >  bash subshells vs bash -c
bash subshells vs bash -c

Time:07-30

Bash subshells (cmd1;cmd2) whill run in a sub bash process, while it can access the variable not exported, how this can be? Meanwhile, bash -c structure can not access unexported variable but it also run in a new shell,so what's the difference?

x=1
(echo $x)
bash -c 'echo $x'

CodePudding user response:

Both subshell and bash -c contexts can access exported variables. To export a variable, one declares the variable as exported (e.g., declare -x VAR) or specifically exports it (export VAR). Your example, it seems, does not export x.

More of the parent context is inherited by subshells (e.g., ( ... )), than are by specific command executions (e.g., bash -c ...).

For example, the following items are inherited by subshells:

  • Current working directory; e.g., as set with cd, pushd, and/or popd
  • Directory stack (DIRSTACK); e.g., as affected by cd, pushd, popd
  • File creation mask; e.g., as set with umask
  • File handles/descriptors; e.g., initially and as affected by exec redirections
  • Settings; e.g., as affected by set, shopt, and alias
  • Shell variables and functions; e.g., as set with declare and =
  • Exported variables and functions; e.g., as declared with declare -x or exported with export
  • Signal traps for ERR; e.g., as set with trap ... ERR
  • Certain special shell parameters; e.g., PPID

For example, the following items are inherited by command executions (w. bash -c):

  • Current working directory; e.g., as set with cd, pushd, and/or popd
  • File creation mask; e.g., as set with umask
  • File handles/descriptors; e.g., initially and as affected by exec redirections
  • Exported variables and functions; e.g., as declared with declare -x or exported with export

For additional detail, check out the Bash manpage, starting with the COMMAND EXECUTION ENVIRONMENT section.

Note: Each command in a pipeline executes in dedicated processes/subshells. With lastpipe enabled, the final pipeline command may run within the outer shell process.

Note: Other than when a command list is fully backgrounded with a trailing &, command lists are executed within the current shell process. When backgrounded, command lists are executed in a dedicated process/subshell.

CodePudding user response:

  1. Assume that I have written following line inside $HOME/.bashrc file using cygwin in Windows.

    export testing="testing$$"
    

    After this I do Windows R => bash.exe

    $ echo $testing
    testing7853
    
  2. I open "cmd.exe"

    Inside that command prompt, I type

    C:> bash.exe -c "echo [$testing]"
    []
    
    C:>
    

    Reason:

    When we execute bash.exe it'll execute ~/.bashrc and other related dependent default profile files. If we execute bash.exe -c "related command" then .bashrc is not executed.

    We are informing bash to execute related command. If you need that environment variable available inside bash.exe -c execute:

    C:\Windows\System32\rundll32.exe sysdm.cpl,EditEnvironmentVariables
    

    Set your required environment variable. For example I set certs environment variable.

    C:>bash.exe -c "echo [$certs]"
    [C:\apache-tomcat\certs]
    

    When we execute bash.exe it is a process waiting for the user input to exit from that process.

    When we execute bash.exe -c, a process is created. It will execute required commands and exit from that process.

    C:\Windows\System32\tasklist.exe | grep bash
    

    The above command will display related output of running process.

  • Related