'Copy current command at bash prompt to clipboard
I would like a quick keyboard command sequence to copy the current command at a bash prompt to the clipboard.
So that, for example, to copy the last bash command to the clipboard, I'd press up+[some command sequence]
to copy it. Or, for example, to search for a command in bash hisory, I'd use ctrl+r, search, display it on the command prompt, and then [some command sequence]
to copy it, etc.
My current solution is using bash pipes: Pipe to/from the clipboard
So, to copy the previous command to clipboard:
echo "!!" | pbcopy
Which isn't too terrible, but what if the command to copy isn't the last command, etc.
What's the proper way to achieve what I'm trying to achieve here?
Solution 1:[1]
Taking @Lauri's post for inspiration, here's a solution using the bind command:
bind '"\C-]":"\C-e\C-u pbcopy <<"EOF"\n\C-y\nEOF\n"'
ctrl-] then will copy whatever is on the current bash prompt to the clipboard.
To make it persistent, you can add the bind command as above to your ~/.bashrc
, or you can strip off the outer quotes and remove the 'bind' part of the call and add the result to your ~/.inputrc
.
Non-OS-X users will have to swap pbcopy out with the appropriate command, probably xclip.
A quoted heredoc was used instead of a an echo+pipe technique so that both single and double quotes in the command at the bash prompt are preserved. With this technique, for example, I was able to hit ctrl-], copy the actual bind command from the terminal prompt, and paste it here in the answer. So the heredoc technique handles all of the special characters in the bind command here.
Solution 2:[2]
You can use READLINE_LINE
with bind -x
in bash 4:
copyline() { printf %s "$READLINE_LINE"|pbcopy; }
bind -x '"\C-xc":copyline'
You can install bash 4 and make it the default login shell by running brew install bash;echo /usr/local/bin/bash|sudo tee -a /etc/shells;chsh -s /usr/local/bin/bash
.
I also use this function to copy the last command:
cl() { history -p '!!'|tr -d \\n|pbcopy; }
Solution 3:[3]
I spent a decent amount of time today writing a simple zsh implementation for macOS; usage is as follows:
example command: git commit -m "Changed a few things"
command that copies: c git commit -m "Changed a few things"
# The second command does not actually execute the command, it just copies it.
# Using zsh, this should reduce the whole process to about 3 keystrokes:
#
# 1) CTRL + A (to go to the beginning of the line)
# 2) 'c' + ' '
# 3) ENTER
preexec()
is a zsh hook function that gets called right when you press enter, but before the command actually executes.
Since zsh strips arguments of certain characters like ' " ', we will want to use preexec()
, which allows you to access the unprocessed, original command.
Pseudocode goes like this:
1) Make sure the command has 'c '
in the beginning
2) If it does, copy the whole command, char by char, to a temp variable
3) Pipe the temp variable into pbcopy
, macOS's copy buffer
Real code:
c() {} # you'll want this so that you don't get a command unrecognized error
preexec() {
tmp="";
if [ "${1:0:1}" = "c" ] && [ "${1:1:1}" = " " ] && [ "${1:2:1}" != " " ]; then
for (( i=2; i<${#1}; i++ )); do
tmp="${tmp}${1:$i:1}";
done
echo "$tmp" | pbcopy;
fi
}
Go ahead and stick the two aforementioned functions in your .zshrc file, or wherever you want (I put mine in a file in my .oh-my-zsh/custom
directory).
If anyone has a more elegant solution, plz speak up. Anything to avoid using the mouse.
Solution 4:[4]
If xsel
is installed on your system you can add this in .inputrc :
C-]: '\C-e\C-ucat <<"EOF" | tr -d "\\n" | xsel -ib\n\C-y\nEOF\n'
Alternatively, if xclip
is installed you could add this:
C-]: '\C-e\C-ucat <<"EOF" | tr -d "\\n" | xclip -se c\n\C-y\nEOF\n'
Notice: Used code from @Clayton's answer.
Solution 5:[5]
I use history
to find the command number that I am looking for, then I do:
echo "!command_number" | xclip -in
Solution 6:[6]
$ history | cut -c 8- | tail -1 | pbcopy
or in .zshrc file add an alias
alias copy='history | cut -c 8- | tail -1 | pbcopy'
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Lri |
Solution 3 | |
Solution 4 | Addison |
Solution 5 | Stephen Rauch |
Solution 6 | Deepak Dubey |