opisanoob22
opisanoob22

Reputation: 1

Bash: Assign command to a variable

Below I have an example which confuses me a bit, any help would be appreciated.

I bind a normal command line command (ls) to a new variable. If I echo it it the output is just the command (ls) but if I just use the variable without echo i get the result of the command but why?? Is it because $listdir gets translated to ls so I just get the output? And if I use the echo command it will be interpreted as a string?

router@test:~/scripting$ listdir=ls
router@test:~/scripting$ echo "$listdir"
ls

----- VS ----
router@test:~/scripting$ $listdir
basicLoop.sh         fileflood.sh .......

Thank you for any help!

Upvotes: 0

Views: 890

Answers (2)

joshmeranda
joshmeranda

Reputation: 3251

When bash is interpreting the commands you feed to it, the first thing it will do is expand any expansions it is given. So when you give it $listdir by the time bash starts to execute the value it is given, all it knows is that it was given the value ls. It does not care where the value came from, only what the value is.

Lets look at the trace given after running set -x, which instructs bash to prints to stderr after expansion and before execution:

$> echo $listdir
+ echo ls
ls

$> $listdir
+ ls
file_0 file_1

As you can see, in the second line, bash will attempt to run the command ls just as if you have explicity called ls or even /usr/bin/ls

Edit

Expansion isn't the first step in in shell evaluation, see @Gordon Davisson's comment for details

Upvotes: 1

jarmuszz
jarmuszz

Reputation: 11

By doing listdir=ls you literally assign a string "ls" to the $listdir variable. So if you run echo $listdir now it will just expand into echo ls, which (as you may have guessed) will just print "ls" onto a screen. If you want to store a result of a command into a variable you can wrap the command in `` or $() (eg. listdir=$(ls) or listdir=`ls`).

jarmusz@emacs~$ listdir=`ls`
jarmusz@emacs~$ echo "$listdir"
dls
docs
music
...

If you want to store just a name of the command and run it later you can do it like this:

jarmusz@emacs~$ listdir=ls
<some other commands...>
jarmusz@emacs~$ echo `$listdir`
dls docs music ...

In this example, echo `$listdir` will expand into echo `ls` and then into echo dls docs music...

Upvotes: 1

Related Questions