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.

  1. If the arguments passed execute properly as a command (return 0), the results of the command are copied to the clipboard
  2. 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)
  3. Failing all of that, the arguments themselves are copied as a string
  4. 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


$ 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 "Usage: copy [command or text]"
		echo "  or pipe a command: [command] | copy"

	local output
	local res=false
	local tmpfile="${TMPDIR}/copy.$RANDOM.txt"
	local msg=""

	if [[ $# == 0 ]]; then
		msg="Input copied to clipboard"
		local cmd=""
		for arg in $@; do
			cmd+="\"$(echo -en $arg|sed -E 's/"/\\"/g')\" "
		output=$(eval "$cmd" 2> /dev/null)
		if [[ $? == 0 ]]; then
			msg="Results of command are in the clipboard"
			if [[ -f $1 ]]; then
				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"
							msg+="File \"$arg\" is not plain text.\n"
				msg="Text copied to clipboard"

	$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.

Brett Terpstra

Brett is a writer and developer living in Minnesota, USA. You can follow him as ttscoff on Twitter, GitHub, and Mastodon. Keep up with this blog by subscribing in your favorite news reader.

This content is supported by readers like you.

Join the conversation