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

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.bashraw
"
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.