4

In bash, I know of 3 "args from previous command" shortcuts. They are:

  1. !^ → first arg, spaces preserved;
  2. $_ → last arg, spaces not preserved;
  3. !* → all args, spaces preserved;

So are there any more arg vars/shortcuts like that? :)


the $_ is useful when I call a file with one command, that's say in a different [long named] directory, then want to call it again in my next command [i.e. $ stat a\ b\ c/sub/folder/example.txt; mv $_ . ], except when there are spaces in it, it does not work.

Why doesn't $_ preserve spaces? To see what I mean type this:

$ echo "1" "One String Quoted"; for i in $_; do echo \"$i\"; done and compare with

$ echo 1 2 "3 4 5"; then press enter then: $ for i in !*; do echo \"$i\" done;

Can you also explain why you have to press enter ^ then do the "for" loop in order for !* to work? [And why the $_ works without having to press enter (AKA, you can use ";" to combine the commands)]

4 Answers 4

2

$ does variable expansion while ! is history expansion. For ! to access the arguments you must have added the command to the bash history, which happens on execution / when pressing enter.

2

$_ preserves spaces just fine. Otherwise, it'd be giving you either a jumbled mess or just the last half of the command. What you want is to add quotes around $_ so that the command that is receiving it preserves the spaces, too.

So, in your example:

$ stat a\ b\ c/sub/folder/example.txt; mv "$_" .
1

$_ will preserve spaces fine if you quote it properly "$_". It behaves differently from the others because it's a separate mechanism from history substitution.

Another mechanism you might want to look at is the fc command.

1

Use !# to access parameters on the current line:

$ echo 1 2 "3 4 5"; for i in !#:1-3; do echo ">$i<"; done
1 2 3 4 5
>1<
>2<
>3 4 5<

See history expansion in the bash manual.

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