3

I tried the following commands

variable='one|name'
echo $variable

The output is

one|name

whereas echo one|name gives an error No command 'name' found. This is reasonable because bash treats | as a pipe and tries to execute command name with one as input.

But why does echo $variable print one|name? After Parameter and Variable expansion, shouldn't it be equivalent to echo one|name?

Version:

GNU bash, version 4.3.11(1)-release (i686-pc-linux-gnu)
  • 1
    How would you like it if it were variable='foo|rm -rf /'? – Stéphane Chazelas Jan 7 '15 at 13:52
6

No, it shouldn't, because of the way bash operate the command.

When you type echo one|name, bash parse the command, treats | as a pipe token, so | perform pipeline.

When you type echo $variable, because token parsing occur before variable expansion, bash parsing the command into two parts, echo and $variable. After that, it performs variable expansion, expand $variable to one|name. In this case, one|name is a string, | is a part of string and can not be treated as a pipe token (of course, the token recognition phrase was done). The only thing it can be special if IFS variable contains |, bash will use | as delimiter to perform field spliting:

$ variable='one|name'
$ IFS='|'
$ echo $variable
one name
  • Wow! didn't consider the parsing part. – nitishch Jan 7 '15 at 13:52
1

The reason is because of the way Bash expands the variable.

Instead of expanding the variable to one|name it expands the variable to "one|name". So here as the value is enclosed within quotes they are treated as string instead of a command.

Below is the strace output of the command which shows how the command gets expanded.

$ variable='one|name'
$ strace echo $variable 
execve("/bin/echo", ["echo", "one|name"], [/* 33 vars */]) = 0
brk(0)                                  = 0x9cc7000
  • Does this happen for all variable expansions? – nitishch Jan 7 '15 at 13:40
  • 3
    No, it's not the way bash expands variables. It's the way bash parsing the command. – cuonglm Jan 7 '15 at 13:46
  • But the strace command is interesting. Didn't know it before. – nitishch Jan 7 '15 at 13:56
  • yes this is the way variables gets expanded in bash. gnu.org/software/bash/manual/html_node/… give you details on how shell expansion happens. – Kannan Mohan Jan 7 '15 at 13:59
-2

The quotes are part of the string you created.

If you did

variable=one|name
echo $variable

the result would be as expected. But you are only able to do this in a script (thanks for the helpful comment).

  • variable=one|name itself would give an error – nitishch Jan 7 '15 at 13:43
  • True, you have to put it in a script, I adjust the answer. Thank you! – ddeimeke Jan 7 '15 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.