What is the difference between an inline variable assignment and a regular one in Bash?
The format VAR=value command
sets the variable VAR
to have the value value
in the environment of the command command
. The spec section covering this is the Simple Commands. Specifically:
Otherwise, the variable assignments shall be exported for the execution environment of the command and shall not affect the current execution environment except as a side-effect of the expansions performed in step 4.
The format VAR=value; command
sets the shell variable VAR
in the current shell and then runs command
as a child process. The child process doesn't know anything about the variables set in the shell process.
The mechanism by which a process exports (hint hint) a variable to be seen by child processes is by setting them in its environment before running the child process. The shell built-in which does this is export
. This is why you often see export VAR=value
and VAR=value; export VAR
.
The syntax you are discussing is a short-form for something akin to:
VAR=value
export VAR
command
unset -v VAR
only without using the current process environment at all.
What's the difference between env and set (on Mac OS X or Linux)?
Long story short: set
can see shell-local variables, env
cannot.
Shells can have variables of 2 types: locals, which are only accessible from the current shell, and (exported) environment variables, which are passed on to every executed program.
Since set
is a built-in shell command, it also sees shell-local variables (including shell functions). env
on the other hand is an independent executable; it only sees the variables that the shell passes to it, or environment variables.
When you type a line like a=1
then a local variable is created (unless it already existed in the environment). Environment variables are created with export a=1
What is the difference between global scope and environment?
TL;DR The global scope is initialized from the environment at startup, but is not the same as the environment.
The environment is a set of strings of the form <name>=<value>
provided by the parent process. On startup, the shell takes each string whose <name>
portion is a valid shell identifier and creates a variable in the global scope with that name.
For example, an environment string FOO=3
becomes a shell variable named FOO
with the value 3
.
On the other hand, an environment string like 10=6
is ignored by the shell, because 10
is not a valid shell identifier. The string remains in the environment, though, to be passed on to any child processes that might expect such a string. [UPDATE: The POSIX spec does not require such strings to be ignored; a conforming shell could either keep or discard them.]
There are also local variables, created by commands like local
and declare
inside a function definition. For example:
$ foo () { declare x; x=3; echo "$x"; }
$ x=2
$ foo
3
$ echo "$x"
2
x=2
created (or changed the value of) a variable in the global scope. Inside the function, declare x
created a local variable. Changes to that variable did not affect the global by the same name.
The -g
option to declare
lets you make the name x
inside the function refer to the global scope, rather than creating a local variable.
$ foo () { declare -g x; x=3; echo "$x"; }
$ x=2
$ foo
3
$ echo "$x"
3
How to check if an environment variable exists and get its value?
[ -z "${DEPLOY_ENV}" ]
checks whether DEPLOY_ENV
has length equal to zero. So you could run:
if [[ -z "${DEPLOY_ENV}" ]]; then
MY_SCRIPT_VARIABLE="Some default value because DEPLOY_ENV is undefined"
else
MY_SCRIPT_VARIABLE="${DEPLOY_ENV}"
fi
# or using a short-hand version
[[ -z "${DEPLOY_ENV}" ]] && MyVar='default' || MyVar="${DEPLOY_ENV}"
# or even shorter use
MyVar="${DEPLOY_ENV:-default_value}"
Use environment variable in word within command
There are no environment variables in your code, only shell variables.
- Shell variables may also be environment variables (exported variables such as
$PATH
that are visible to all child processes, whether they're shells or not), but that's not the case here.
- Shell variables may also be environment variables (exported variables such as
Shell variable names must be disambiguated from adjacent characters that could be part of a syntactically legal variable name by enclosing them in
{...}
-${i}
, in your case.Unless you specifically want shell-variable references (possibly embedded in unquoted tokens) subjected to shell expansions, notably word-splitting and globbing, double-quote them -
"s${i}a"
in your case.Use an arithmetic, C-style loop to create a memory-efficient loop with a variable number of iterations.
To put it all together:
$ n=5; for (( i = 1; i <= n; ++i )); do echo "s${i}a"; done
s1a
s2a
s3a
s4a
s5a
environmental variables vs. global variables
They don't mean the same. "global" is a programming language idea, "environment variable" is an operating system idea. So, they're not really related, and conceptually quite different!
Since you now know that, and both terms are easily researchable ("environment variable" on wikipedia, global variable on the Python.org language tutorial), I'm not going to write an introduction into two completely unrelated topics here – I simply couldn't put it any better.
Note that as Python beginner, you will not have to deal with explicitly global variables often. In fact, global
is usually a keyword you should avoid, it often is a sign that you forgot to correctly think of what goes in and out of a function.
Related Topics
Faster Forking of Large Processes on Linux
Prevent File Descriptors Inheritance During Linux Fork
How to Use Xargs to Copy Files That Have Spaces and Quotes in Their Names
How to Get the Name of the Current Git Branch into a Variable in a Shell Script
Why No Output Is Shown When Using Grep Twice
Awk - How to Delete First Column with Field Separator
Execute Combine Multiple Linux Commands in One Line
Why Child Process Still Alive After Parent Process Was Killed in Linux
Perl Command Line Multi-Line Replace
How to Increase Ble Advertisement Frequency in Bluez
Anything Like Dos2Unix for Windows
Generating a Sha-256 Hash from the Linux Command Line
Node.Js: Cannot Find Module 'Request'
Specifying Udp Receive Buffer Size at Runtime in Linux
Symbols from Convenience Library Not Getting Exported in Executable