Ubuntu – How to execute the last line of output in bash

bash

I know I can run the last command in bash, with !!, but how can I run the last line of output?

I am thinking of the use case of this output:

The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

But I don't know how I can run that. I'm thinking of something like the !!, maybe @@ or similar?


Super User has this question too.

Best Answer

The command $(!! |& tail -1) should do:

$ git something
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

$ $(!! |& tail -1)
$(git something |& tail -1)
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
git-man liberror-perl

As you can see the sudo apt-get install git command is running.

EDIT : Breaking down $(!! |& tail -1)

  • $() is the bash command substitution pattern

  • bash will expand !! to the last executed command

  • |& part is tricky. Normally pipe | will take the STDOUT of the left sided command and pass it as STDIN to the command on the right side of |, in your case the previous command prints its output on STDERR as an error message. So, doing | would not help, we need to pass both the STDOUT and STDERR (or only STDERR) to the right sided command. |& will pass the STDOUT and STDERR both as the STDIN to the right sided command. Alternately, better you can only pass the STDERR:

    $(!! 2>&1 >/dev/null | tail -1)
    
  • tail -1 as usual will print the last line from its input. Here rather than printing the last line you can be more precise like printing the line that contains the apt-get install command:

    $(!! 2>&1 >/dev/null | grep 'apt-get install')