Bash History in Script – Using ‘!#:*’

bashcommand history

I have been reading through the study guides for the LPIC-1.

echo "This is a sentence. " !#:* !#:1->text3

I'm having trouble understanding how the above line of code repeats the echo command multiple times. I know that it is using a feature of bash's history but I can't find any documentation on !#:* or !#:1. Could someone explain this for me?

Best Answer

Yes, this is using history.  !# is a history event designator that refers to the entire command line typed so far.  :* is a word (range) designator that refers to all of the words, except the 0th.  So, after you have typed echo "This is a sentence. ", then !#:* expands to "This is a sentence.  ".  And x-y (where x and y are integers) is a word (range) designator that refers to word number x through word number y.  If y is omitted (x-), this is interpreted to mean word number x through the second to last word.  So, after your “entire command line typed so far” stands as

echo "This is a sentence. " "This is a sentence. "

then !#:1- expands to "This is a sentence. ", because each of the quoted "This is a sentence. " strings counts as one word, and so !#:1- is equivalent to !#:1 (just word number 1).  So you end up with

echo "This is a sentence. " "This is a sentence. " "This is a sentence. " >text3

The fact that the - and the > appear together in the command is just a confusion; they don’t interact.  And the fact that “This is a sentence.” is quoted obscures what is going on; if you said

echo This is a sentence. !#:* !#:1-

it would expand to

echo This is a sentence. This is a sentence. !#:1-

and thence to

echo This is a sentence. This is a sentence. This is a sentence. This is a

(because !#:1- expands to word number 1 through the second to last word.)

Related Question