A universal clipboard command for Bash
I frequently use pbcopy
in the shell to get output to the OS X clipboard. I’m constantly using [command] | pbcopy
, and figured it would be worth making a little easier, so I wrote this little function this morning.
It works in a few ways, attempting to intelligently figure out what it’s supposed to do.
- If the arguments passed execute properly as a command (return 0), the results of the command are copied to the clipboard
- If the first argument is a path to an existing plain text file, the contents of that file are copied, and any further arguments are tested as text files (functions like
cat
for the clipboard) - Failing all of that, the arguments themselves are copied as a string
- If there are no arguments, it waits for STDIN, meaning you can pipe to it as a shortcut for
pbcopy
, or manually enter text and end entry with^d
Examples
$ copy pwd
=> puts the current path in your clipboard
$ copy !!
=> puts the results of the previous command in your clipboard
$ copy curl http://brettterpstra.com/bookmarklets/answered.js
=> puts the "answered" bookmarklet on the clipboard
$ curl http://brettterpstra.com/bookmarklets/answered.js | copy
=> same as above, just an alias for `| pbcopy`
$ copy ~/.bash_profile ~/.bashrc ~/.inputrc
=> puts the concatenated contents of your login profiles
in the clipboard
$ copy *.{md,markdown,mmd,mdown}
=> copies text of all the Markdown files in the current directory
$ copy just dicking around in the shell because 6 IN THE MORNING
=> puts text on your clipboard
$ date | copy
=> puts the current date in your clipboard via piped output
Just add the function below to ~/.bash_profile
or to any file/folder that gets sourced during login. Change the name of the function as needed… if c
weren’t already aliased to clear
for me, I’d have just named it that.
copy() {
if [[ $1 =~ ^-?[hH] ]]; then
echo "Intelligently copies command results, text file, or raw text to"
echo "OS X clipboard"
echo
echo "Usage: copy [command or text]"
echo " or pipe a command: [command] | copy"
return
fi
local output
local res=false
local tmpfile="${TMPDIR}/copy.$RANDOM.txt"
local msg=""
if [[ $# == 0 ]]; then
output=$(cat)
msg="Input copied to clipboard"
res=true
else
local cmd=""
for arg in $@; do
cmd+="\"$(echo -en $arg|sed -E 's/"/\\"/g')\" "
done
output=$(eval "$cmd" 2> /dev/null)
if [[ $? == 0 ]]; then
msg="Results of command are in the clipboard"
res=true
else
if [[ -f $1 ]]; then
output=""
for arg in $@; do
if [[ -f $arg ]]; then
type=`file "$arg"|grep -c text`
if [ $type -gt 0 ]; then
output+=$(cat $arg)
msg+="Contents of $arg are in the clipboard.\n"
res=true
else
msg+="File \"$arg\" is not plain text.\n"
fi
fi
done
else
output=$@
msg="Text copied to clipboard"
res=true
fi
fi
fi
$res && echo -ne "$output" | pbcopy -Prefer txt
echo -e "$msg"
}
Ryan Irelan has produced a series of shell trick videos based on BrettTerpstra.com posts. Readers can get 10% off using the coupon code TERPSTRA
.