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/orpopd
- Directory stack (
DIRSTACK
); e.g., as affected bycd
,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
, andalias
- Shell variables and functions; e.g., as set with
declare
and=
- Exported variables and functions; e.g., as declared with
declare -x
or exported withexport
- Signal traps for
ERR
; e.g., as set withtrap ... 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/orpopd
- 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 withexport
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:
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
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 executebash.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.