Reputation: 175
There are 3 files (a
, b
and c
), all with 777
permissions:
$ ls
a b c
The above files have the following contents:
$ cat a
#!/bin/bash
export A=aaa
$ cat b
#!/bin/bash
source ./a
echo $A
$ cat c
#!/bin/bash
source ./a | >> log
echo $A
The only difference between b
and c
is | >> log
:
$ diff b c
2c2
< source ./a
---
> source ./a | >> log
When b
is executed it outputs the expected aaa
:
$ ./b
aaa
When c
is executed it outputs, for me, an unexpected blank row instead of the expected aaa
, and the log
file that script c
created is empty:
$ ./c
$ cat log
$
Clearly, there is something about source
and |
that I have yet to learn.
Could someone please enlighten me regarding why c
does not output aaa
?
Upvotes: 0
Views: 1883
Reputation: 32954
In Bash, the first command in a pipeline will always be executed in a subshell, so any variables that it imports are lost. But a pipeline is not what you want in the first place. With foo | >> file
, it redirects the output of foo
into a null command, then the output of the null command (which is null) is appended to the file. I'm not sure why Bash allows the second command in the pipeline to be null when there's a redirection.
You want command >> file
, i.e.
$ cat c
#!/bin/bash
source ./a >> log
echo $A
Although source ./a
doesn't produce any output.
Upvotes: 2
Reputation: 295373
Use a process substitution instead of a pipeline:
source ./a > >(tee -a log)
That way your source
command runs in the original shell.
Alternately, stop creating a pipeline at all:
source ./a >>log
Upvotes: 7