简体   繁体   中英

bash subshells vs bash -c

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'

Both subshell and bash -c contexts can access exported variables. To export a variable, one declares the variable as exported (eg, 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 (eg, (... ) ), than are by specific command executions (eg, bash -c... ).

For example, the following items are inherited by subshells:

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

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

  • Current working directory; eg, as set with cd , pushd , and/or popd
  • File creation mask; eg, as set with umask
  • File handles/descriptors; eg, initially and as affected by exec redirections
  • Exported variables and functions; eg, 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.

  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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM