Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable value doesn't change in bash script [duplicate]

Tags:

bash

shell

Running the following code:

a=one; echo $a
a=two echo $a
a=three echo $a >$a

results in

one

one

and a created file with name "one" with content "one"

Why the variable didn't change to two at line 2 and to three at line 3?

like image 482
Petar D. Avatar asked Dec 13 '22 20:12

Petar D.


1 Answers

An assignment does something different when it's used as a command by itself vs. as a prefix to some other command (e.g. echo). When used as a command by itself, it sets a shell variable to that value. When used as a prefix to some other command, it sets an that variable in the environment of the command but not in the shell.

So, look at the first example, a=one; echo $a, where the semicolon makes this two commands on the same line. The first command sets the shell variable a to the value "one", and then for the second command the shell expands a to "one", and then passes that as an argument to echo.

In the second example, a=two echo $a, the assignment is a prefix to the echo command, so echo will be executed with a set to "two" in its environment. But the $a gets expanded by the shell, not by the echo command, and a is still set to "one" as a shell variable, so that value gets used.

The third example, a=three echo $a >$a, is a lot like the second. The shell expands both $as to "one" (since that's the value of the shell variable), then executes echo one with a set to "three" in its environment and output directed to a file named "one".

BTW, there's another complication I haven't mentioned: exporting shell variables. By default, shell variables are not set in the environment of commands that the shell executes. That is, they are shell variables, not environment variables. But if you export a shell variable, it becomes an environment variable and will be inherited by subsequent commands run by that shell. So...

  • This sets a shell variable, which will not be passed on to commands' environments:

    a=one
    
  • This sets an environment variable for this command only, not for the shell or later commands:

    b=two somecommand
    
  • This sets an environment variable in the shell, so it'll be available to the shell and all subsequent commands run from that shell:

    export c=three
    
  • This does the same thing:

    d=four
    export d
    

    You can export shell variables to the environment before, after, or while assigning to them.

like image 169
Gordon Davisson Avatar answered Dec 26 '22 17:12

Gordon Davisson