What is the difference between:
prompt$ TSAN_OPTIONS="suppressions=/somewhere/file" ./myprogram
and
prompt$ TSAN_OPTIONS="suppressions=/somewhere/file"
prompt$ ./myprogram
The thread-sanitizer library gives the first case as how to get their library (used within myprogram) to read the file given in options. I read it, and assumed it was supposed to be two separate lines, so ran it as the second case.
The library doesn't use the file in the second case, where the environment variable and the program execution are on separate lines.
What's the difference?
Bonus question: How does the first case even run without error? Shouldn't there have to be a ; or && between them? The answer to this question likely answers my first...
To complement Etan Reisner's helpful answer:
It's important to distinguish between shell variables and environment variables:
Note: The following applies to all POSIX-compatible shells;
bash
-specific extensions are marked as such.A shell variable is a shell-specific construct that is limited to the shell that defines it (with the exception of subshells, which get their own copies of the current shell's variables),
whereas an environment variable is inherited by any child process created by the current process (shell), whether that child process is itself a shell or not.
Note that all-uppercase variable names should only be used for environment variables.
Either way, a child process only ever inherits copies of variables, whose modification (by the child) does not affect the parent.
-a
shell option (set withset -a
, or passed to the shell itself as a command-line option) can be used to auto-export all shell variables.Thus,
TSAN_OPTIONS="suppressions=/somewhere/file"
- are ONLY shell variables, but NOT ALSO environment variables,TSAN_OPTIONS="suppressions=/somewhere/file" ./myprogram
- in which case they are ONLY environment variables, only in effect for THAT COMMAND.Shell variables become environment variables as well under the following circumstances:
$HOME
export varName[=value]
or, inbash
, also withdeclare -x varName[=value]
bash
, usingdeclare
without-x
, or usinglocal
in a function, creates mere shell variables-a
shell option is in effect (with limited exceptions)Once a shell variable is marked as exported - i.e., marked as an environment variable - any subsequent changes to the shell variable update the environment variable as well; e.g.:
export -p
prints all environment variablesunset [-v] MYVAR
undefines shell variable$MYVAR
and also removes it as an environment variable, if applicable.bash
:export -n MYVAR
- this removesMYVAR
from the environment, but retains its current value as a shell variable.declare -p MYVAR
prints variable$MYVAR
's current value along with its attributes; if the output starts withdeclare -x
,$MYVAR
is exported (is an environment variable)The format
VAR=value command
sets the variableVAR
to have the valuevalue
in the environment of the commandcommand
. The spec section covering this is the Simple Commands. Specifically:The format
VAR=value; command
sets the shell variableVAR
in the current shell and then runscommand
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 seeexport VAR=value
andVAR=value; export VAR
.The syntax you are discussing is a short-form for something akin to:
only without using the current process environment at all.