Reputation: 21
Can someone explain the difference in scope of environment variables in the following 4 examples?
❯❯❯ b=1 echo $b
❯❯❯ b=1; echo $b
1
❯❯❯
❯❯❯ cat gen.sh
#!/bin/bash
echo $a
❯❯❯
❯❯❯ a=1 ./gen.sh
1
❯❯❯ a=1; ./gen.sh
Upvotes: 0
Views: 761
Reputation: 4704
Expansion of $parameters is done before executing a command, using the current environment.
Assigning a parameter does not automatically export it to child processes (commands), but only on subsequent invocations of commands (in their command line, as per rule #1).
But, a command in the form "a=b command" has an assignment that is exported to the command, but only temporarily - only for that single command invocation.
Given the three rules above:
❯❯❯ b=1 echo $b
gets first translated to: b=1 echo ""
... and prints nothing.
❯❯❯ b=1; echo $b
works, because there are two distinct commands, as if they were put on two different lines. The first is expanded and sets a variable; then the second is expanded.
#!/bin/bash
echo $a
(this script prints the $a found in the environment).
❯❯❯ a=1 ./gen.sh
This works because a=1 is exported, so gen.sh founds it in the environment.
❯❯❯ a=1; ./gen.sh
This does not work because a=1 is set but not exported to child processes; so gen.sh starts but does not find $a in the environment. The following instead would work:
❯❯❯ export a=1; ./gen.sh
Upvotes: 2