2

Please advice why this happens.

from a Linux bash shell:

ps
PID TTY          TIME CMD
20406 pts/0    00:00:01 bash
26896 pts/0    00:00:00 ps

I run the follwing

str="a b c d"
printf "%s\n"  ` echo $str `
a
b
c
d

but from bash script

#!/bin/bash
.
.
.
.

str="a b c d"
printf "%s\n"  ` echo $str `

it prints:

a b c d  

while the expected results from script should be like this:

a
b
c
d

What is missing in my bash script? Maybe bash ENV, or something like that?

I run also shopt command from my bash script and these are the results:

  utocd  off
  cdable_vars  off
  cdspell  off
  checkhash  off
  checkjobs  off
  checkwinsize  off
  cmdhist  on
  compat31  off
  compat32  off
  compat40  off
  compat41  off
  direxpand  off
  dirspell  off
  dotglob  off
  execfail  off
  expand_aliases  off
  extdebug  off
  extglob  off
  extquote  on
  failglob  off
  force_fignore  on
  globstar  off
  gnu_errfmt  off
  histappend  off
  histreedit  off
  histverify  off
  hostcomplete  on
  huponexit  off
  interactive_comments  on
  lastpipe  off
  lithist  off
  login_shell  off
  mailwarn  off
  no_empty_cmd_completion  off
  nocaseglob  off
  nocasematch  off
  nullglob  off
  progcomp  on
  promptvars  on
  restricted_shell  off
  shift_verbose  off
  sourcepath  on
  xpg_echo  off
  • 2
    Cannot reproduce this. It seems, that the echo part is additionally double-quoted. Please add bash version and the output of shopt to the question. – jimmij Jan 8 '18 at 17:55
  • @jimmij see please my update – yael Jan 8 '18 at 18:00
  • This might be related to this question posted here. Try echo -e $str instead and see if that works? – imbuedHope Jan 8 '18 at 18:03
  • this not help ( echo -e ) – yael Jan 8 '18 at 18:06
  • 1
    Did you mess with IFS variable, hmm? – jimmij Jan 8 '18 at 18:08
4

I can reproduce this behavior only in two cases:

  1. double-quoted command substitution:

    #!/bin/bash
    
    str="a b c d"
    printf "%s\n"  "`echo $str`"
    
  2. or changed Internal Field Separator (IFS variable), e.g.:

    #!/bin/bash
    
    IFS=,
    str="a b c d"
    printf "%s\n" `echo $str`
    

In both cases output is

$ ./test.sh
a b c d

To repair first case just remove the quotes, and to restore IFS just set it to the default value somewhere above command substitution.

IFS=$' \t\n'

A little bit of explanation why the output is different when IFS changed and what does it have in common with double-quotes?

Lets start from the end:

printf "%s\n" a b c d

is obviously different than

printf "%s\n" 'a b c d'

In the first case we have four separate words, and printf output them one by one adding new line to them. In the second case the whole a b c d is treated as a single word and printf just output it as such to the terminal. And now should be obvious that the output of `echo $str` is treated as a single word when additionally double-quoted.

Now is where IFS starts to play a role. Namely, tt is used to split words after expansions, so with default IFS=$' \t\n' the expression echo a b c d outputs a b c d, but with IFS=, it becomes 'a b c d' - a single world, although quotes were not used explicitly. One can check that more clearly without variable:

$ IFS=,
$ printf "%s\n"  `echo a b c d`
a b c d

$ IFS=$' \t\n'
$ printf "%s\n"  `echo a b c d`
a
b
c
d

As a final note: it is better to use a $() form of command substitution, not backticks, but that's different topic.

  • well done its works – yael Jan 8 '18 at 18:48

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.