The _=
at the start of a line in the output of plain set means that there is a variable called _
(underscore) in bash. And its value is what follows the =
. Like setting a variable named test_var
to 12345
will yield (in bash):
$ test_var=12345
$ set | grep test_var
test_var=12345
$ declare -p test_var
test_var=12345
That special bash variable will be set to the last argument of the previous line:
$ echo "Testing some" "values" "in the shell" "(only bash)" "_=myvar=hello"
Testing some values in the shell (only bash) _=myvar=hello
$ echo "$_"
_=myvar=hello
$ echo "Testing some" "values" "in the shell" "(only bash)" "_=myvar=hello"
Testing some values in the shell (only bash) _=myvar=hello
$ declare -p _
declare -- _="_=myvar=hello"
Note the two =
in that output.
Longer description
When you execute set -a var=99
, three distinct things happen (related to your question):
- A set option (
-a
) (reverse by doing set +a
) to export vars.
- Positional parameters are "set" to what follows the options (
$1
set to var=99
).
- The shell variable underscore
$_
is set to the last parameter (expanded).
set -a
The execution of set -a
marks all subsequent (new or changed) variables as exported (in all shells, except csh
and some related shells).
$ set -a
$ myvariable=wer
$ env | grep myvariable
myvariable=wer
To recover from this setting, just change the -
to a +
:
$ set +a
$ unset myvariable # to erase it from the environment if it
# was exported before the change of set +a
$ myvariable=456544654 # A new value of the variable.
$ env | grep "variable" # No output means the var does not exist
# in the current environment
set var=99
Which should actually be set -- var=99
to avoid interpretation of an option (and set has a lot) with values that start with a dash (-
).
Sets the list of arguments (the list of positional parameters) to that after the --
. That is valid in all reasonable shells (not in csh et al).
Positional arguments are printed with "$@" (or similar "$*", not equal).
$ set -- a=1 b=2 c=3
$ echo "$@"
a=1 b=2 c=3
#_=last_argument
And, the value of the internal shell variable _
change to the last argument of the executed line. That is NOT true in almost all shells (jsh, ash, yash, dash, lksh, mksh, ksh93, attsh and of course csh and tcsh) except bash.
$ echo one two last argument
one two last argument
$ echo "$_"
argument
$ echo This is a new: last_argument
This is a new: last_argument
$ echo "$_"
last_argument
Please note that the value in $_
is the value after expansion:
$ a="A New_Argument"
$ echo Something else to test: "$a"
Something else to test: A New_Argument
$ echo "$_"
A New_Argument
That's why when you execute:
$ set -a myvar=99; set | grep 'myvar'
_=myvar=99
You get a description of the shell variable '$_'. This also works:
$ set -a myvar=99; declare -p _
declare -- _="myvar=99"