Ubuntu – How to copy an entire command line to the clipboard, without the mouse

clipboardcommand linekeyboard

Imagine that I have this line in my terminal:

youtube-dl --get-thumbnail --extract-audio --audio-format mp3 https://www.youtube.com/watch?v=

After testing it, I would like to copy this line above to my clipboard and paste it in some script file. Not the output of the command.
But, doing this without using the mouse. I like to keep my hands at the keyboard only. I think is faster that way, to do some coding 🙂

Best Answer

My answer offers a simple command in three different syntaxes, which all work equally, but one is a bit shorter and easier to type than the second. The third variation is a so-called alias, that means you can assign the command a custom name and call it by executing that without having to remember the complex stuff.

Preparation:

First, install the package xsel which allows you to access the X clipboard from the terminal:

sudo apt-get install xsel

Command variation 1 (short):

After that, you can type the following line to copy the previous command to the clipboard:

xsel -ib <<<!!:q

If you want to copy the second latest command, replace !! with !-2, for the third latest use !-3 and so on.

To explain what you're running, here a short break down of the command:

  • xsel is a command-line tool to access the X clipboards.
    For more info, read it's manpage online Manpage icon or by running man xsel.

    • The -i parameter tells xsel to read from the stdin (usually this means keyboard input, but we're going to redirect something here)
    • The -b parameter specifies to use the clipboard instead of X's "primary" or "secondary" selections.
  • <<< is a special Bash syntax called "Here String".
    It basically expands (not evaluates!) the argument (only one!) after it and redirects it as string to the stdin (standard input) of the command before/after which it stands.

  • !!:q is called a "bang command" for history expansion in bash. It replaces itself with any previously typed command line.
    For more info, read it's local manpage by running man history (online manpage is not helpful).

    • The !! stands for the previous command line and is a synonym for !-1.
      Obviously !-2 means then the second last command line. Don't forget the minus sign -, otherwise it will return the 2nd (3rd/...) command you have ever typed.
    • The :q modifies the bang command and tells bash to enclose the substitution in single quotes (') to prevent further expansion by the shell.

Command variation 2 (slightly longer):

echo !!:q | xsel -ib
  • echo has the simple job of printing all its arguments to the terminal's stdout.

  • !!:q is called a "bang command" for history expansion in bash. It replaces itself with any previously typed command line.

    • The !! stands for the previous command line and is a synonym for !-1. Obviously !-2 means then the second last command line. Don't forget the minus sign -, otherwise it will return the 2nd (3rd/...) command you have ever typed.
    • The :q modifies the bang command and tells bash to enclose the substitution in single quotes (') to prevent further expansion by the shell.
  • | is a pipe. It redirects the terminal output ("stdout") of the command before it to the terminal input ("stdin") of the command after it.

  • xsel is a command-line tool to access the X clipboards.
    For more info, read it's manpage online Manpage icon or by running man xsel.

    • The -i parameter tells xsel to read from the stdin (usually this means keyboard input, but we're going to redirect something here)
    • The -b parameter specifies to use the clipboard instead of X's "primary" or "secondary" selections.

Command variation 3 (alias):

A bash alias is a cool thing if you don't want to remember long or complicated commands you often use. You can assign this command to a simple alias name, which you can run instead of the long command to achieve the same.

Unfortunately, as bang commands are a special Bash feature and get expanded before aliases are resolved, you can't simply alias one of the variations above because the !! part will not work. There's a workaround though.

To set the alias, run the following line in your terminal. Note that you may chose any valid Bash variable name instead of copylastcommand:

alias copylastcommand='history -p \!\! | xsel -ib'

This is however only persistent for your current Bash session, which means the alias will vanish after you close the terminal window. You can make it persistent in every of your Bash sessions by adding this line above to the end of your ~/.bashrc file, or to your ~/.bash_aliases file if you have one.

Again, a short break down of the line:

  • alias name='command' is the syntax to set an alias in Bash. The command will be run whenever you execute name from now on.

  • history -p \!\! outputs the previously executed command line to stdout (standard output). Without the -p switch, it would not only print but also run the command again.
    Note that we need to escape the bangs (!) with backslashes (\), because otherwise bash would expand them when we try to set the alias, which makes no sense as they need to be in the alias as they are.
    Again, you can also specify the [n]-th recent command by replacing the second bang with -n, e.g. \!-2.

  • | is a pipe. It redirects the standard output ("stdout") of the command before it to the terminal standard ("stdin") of the command after it.

  • xsel is a command-line tool to access the X clipboards.
    For more info, read it's manpage online Manpage icon or by running man xsel.

    • The -i parameter tells xsel to read from the stdin (usually this means keyboard input, but we're going to redirect something here)
    • The -b parameter specifies to use the clipboard instead of X's "primary" or "secondary" selections.