2

According to tldp.org, bash underscore variable is:

The underscore variable is set at shell startup and contains the absolute file name of the shell or script being executed as passed in the argument list. Subsequently, it expands to the last argument to the previous command, after expansion. It is also set to the full pathname of each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file.


But this answer to How can I repeat a character in Bash? makes an strange use of it:

# exactly the same as perl -E 'say "=" x 100'.
echo -e ''$_{1..100}'\b='

Playing around with this variable I can't make anything out of it's semantics, so the question is what does

  • An string.
  • Followed by $_.
  • Followed by range expansion.
  • Followed by another string

mean in bash?

Sample:

$ echo $_{0..10}         ; echo $_{0..10} | wc

      1       0       1


$ echo ''$_{0..10}''     ; echo ''$_{0..10}'' | wc

      1       0      11


$ echo ''$_{0..10}'x'    ; echo ''$_{0..10}'x' | wc
x x x x x x x x x x x
      1      11      22


$ echo 'x'$_{0..10}''    ; echo 'x'$_{0..10}'' | wc
x x x x x x x x x x x
      1      11      22


$ echo 'ab'$_{0..10}'cd' ; echo 'ab'$_{0..10}'cd' | wc
abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd
      1      11      55
hkoosha
  • 1,136
  • 2
  • 15
  • 30

2 Answers2

5
echo $_{0..10}

The braces are expanded to:

echo $_0 $_1 $_2 $_3 $_4 $_5 $_6 $_7 $_8 $_9 $_10

It prints the values of eleven strangely-named variables named _0, _1, _2, and so on. They're not set—which is why you don't see anything—but if they were, you would:

$ _0=zero _1=one _2=two _3=three _4=four _5=five _6=six _7=seven _8=eight _9=nine _10=ten
$ echo $_{0..10}
zero one two three four five six seven eight nine ten

$ echo ''$_{0..10}'x'

Same thing, but now there's an x after each variable name. It's not part of the variable name. It's a separate, literal character x, as if you'd written:

echo ${_0}x ${_1}x ${_2}x ${_3}x ${_4}x ${_5}x ${_6}x ${_7}x ${_8}x ${_9}x ${_10}x

Now the output when the variables have values is:

$ _0=zero _1=one _2=two _3=three _4=four _5=five _6=six _7=seven _8=eight _9=nine _10=ten
$ echo ''$_{0..10}'x'
zerox onex twox threex fourx fivex sixx sevenx eightx ninex tenx

This should be enough to understand the other examples in your question.

It also shows that the linked answer is a poor way to repeat a string. It relies on these variables being unset. Not recommended.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
0

That is brace expansion.

Read

info bash -n "Brace Expansion"

This expands the last command, stored in $_, with the given numbers.

John Goofy
  • 1,330
  • 1
  • 10
  • 20