clipboard

a utility by the Bored Zo


What it is

clipboard is a command-line tool for getting and setting the clipboard. Simple sample uses:

Getting
clipboard -v foo.txt (pastes into file 'foo.txt')
Setting
echo -n foo | clipboard (copies 'foo' to the clipboard)
clipboard -c foo.txt (copies the contents of file 'foo.txt' to the clipboard)

Requirements


Comparison to pbpaste/pbcopy

pbpaste is the clipboard-interface program that comes with Mac OS X 10.1, and pbcopy and pbpaste are the clipboard-interface programs that come with Mac OS X 10.3 and later (I don't know about 10.0 and 10.2). I did some comparisons between clipboard 2.0 and pbcopy. Here's the output.

clipboard
2.0
pbcopy
from 10.3.3
7.50633.056

The times are in seconds.

Test environment:
Power Macintosh G4 Cube
MPC7400 (G4), 450 MHz
Mac OS X 10.3.3 (Darwin 7.3.0)
zsh 4.2
clipboard 2.0
These are the actual time-trial processes used to calcuate the above times.
% cd ~/Projects/clipboard/clipboard-20
% buildit --fast=G4
gcc -std=c99 clipboard.c -fast -mcpu=G4 -mtune=G4 -s -no-cpp-precomp -framework Carbon -o clipboard
% clipboard --version
clipboard 2.0
Compiled with: 
        Escalating allocation
        Memory-mapped input
        Argument support
        Clipboard concatenation
% du -h ~/Documents/bigger-headers.txt
100M    /Users/boredzo/Documents/bigger-headers.txt
% du -b ~/Documents/bigger-headers.txt
104857600       /Users/boredzo/Documents/bigger-headers.txt

% #with iTunes 4.2 (v72) running and playing
% time clipboard -c ~/Documents/bigger-headers.txt
clipboard -c ~/Documents/bigger-headers.txt  1.76s user 3.47s system 40% cpu 13.005 total
% time clipboard -c ~/Documents/bigger-headers.txt
clipboard -c ~/Documents/bigger-headers.txt  1.69s user 3.66s system 35% cpu 14.996 total
% time clipboard -c ~/Documents/bigger-headers.txt
clipboard -c ~/Documents/bigger-headers.txt  1.96s user 3.64s system 43% cpu 12.797 total
% time pbcopy < ~/Documents/bigger-headers.txt
pbcopy < ~/Documents/bigger-headers.txt  8.29s user 3.55s system 31% cpu 37.668 total
% time pbcopy < ~/Documents/bigger-headers.txt
pbcopy < ~/Documents/bigger-headers.txt  8.13s user 3.68s system 17% cpu 1:06.68 total
% time pbcopy < ~/Documents/bigger-headers.txt
pbcopy < ~/Documents/bigger-headers.txt  8.35s user 3.95s system 17% cpu 1:10.28 total

% #without iTunes running
% time clipboard -c ~/Documents/bigger-headers.txt 
clipboard -c ~/Documents/bigger-headers.txt  1.79s user 4.35s system 65% cpu 9.309 total
% time clipboard -c ~/Documents/bigger-headers.txt
clipboard -c ~/Documents/bigger-headers.txt  1.62s user 4.02s system 85% cpu 6.609 total
% time clipboard -c ~/Documents/bigger-headers.txt
clipboard -c ~/Documents/bigger-headers.txt  1.84s user 3.68s system 83% cpu 6.602 total
% time pbcopy < ~/Documents/bigger-headers.txt     
pbcopy < ~/Documents/bigger-headers.txt  8.49s user 3.59s system 77% cpu 15.515 total
% time pbcopy < ~/Documents/bigger-headers.txt
pbcopy < ~/Documents/bigger-headers.txt  8.02s user 3.41s system 27% cpu 41.447 total
% time pbcopy < ~/Documents/bigger-headers.txt
pbcopy < ~/Documents/bigger-headers.txt  8.13s user 3.42s system 27% cpu 42.207 total

% #computing the averages
% dc
3k #precision: three decimal places

#without iTunes running
9.309 6.609+ 6.602+ 3/p
7.506  #clipboard
15.515 41.447+ 42.207+ 3/p
33.056 #pbcopy

#with iTunes running
13.005 14.996+ 12.797+ 3/p
13.599 #clipboard
37.668 66.68+ 70.28+ 3/p
58.209 #pbcopy

Comparison to toclip

I did a similar comparison against toclip, which is clipboard's only third-party competitor. Unlike clipboard and pbpaste, toclip is $7 shareware. Surprisingly, it does come with source code, so I was able to analyse the two programs and see how they worked differently.

% time toclip < ~/Documents/big-headers.txt
^C
toclip < ~/Documents/big-headers.txt  4612.66s user 27.03s system 77% cpu 1:39:49.12 total

The time shown is the amount of time that had elapsed when the program was interrupted by pressing ctrl-C: one hour, 39 minutes, and 49.12 seconds. this test was run under Mac OS X 10.1.5 running zsh 4.1.1 and toclip 1.0.

Analysis of clipboard 2.0 vs toclip 1.0 (pbpaste isn't open-source):

clipboard 2.0 toclip 1.0
  1. Identify whether to copy and/or paste (for this analysis, we assume we're copying)
  2. Identify source file (for this analysis, we use stdin)
  3. Start with a 64 K increment and initialise the buffer size to this amount
  4. Use fread(2) to read from stdin
  5. Add the increment (still 64 K) to the buffer size
  6. Reallocate buffer to match the new buffer size
  7. Double the increment
  8. Wash, rinse, repeat (steps 4 through 7) until stdin reaches EOF or gets an error
  9. Call PutScrapFlavor to perform the copy
  1. Identify whether to copy and/or paste (for this analysis, we assume we're copying)
  2. Identify source file (for this analysis, we use stdin)
  3. Use read(2) to read 1 K from the file
  4. Create a node for a linked list (using malloc(3))
  5. Create a buffer for the text (using malloc(3)) and attach it to the node
  6. Copy the text (returned from read(2)) to the buffer using snprintf(3)
  7. Wash, rinse, repeat (steps 3 through 6) until stdin reaches EOF or gets an error
  8. Create a contiguous buffer of equal length to the data that was read
  9. Copy the text from each node to the buffer using strncat(3) (freeing each node's buffer but NOT the node - this is, of course, a leak)
  10. Call [pboard setString] to perform the copy

Downloads

1.0
1.0.1
2.0

Version History

1.0
  • Initial release.
1.0.1
  • Added newline translation.
2.0rc1
  • Added command-line arguments. See the full manual for details. The most important arguments are -c (copy), -v (paste), and -b (clear).
  • Clipboard is now smarter about figuring out where it is in the pipeline when you invoke it with no arguments. No more false positives (yea!).
  • Added support for reading directly from regular files. Specify the filename on the command-line. For best results, specify one of the subcommand arguments as well.
2.0rc2
  • Fixed a fatal addressing error in copy_bufs (note to self: --i, not i--).
2.0rc3
  • Fixed an annoying bug in which you got the implicit paste even when requesting an explicit paste (due to implicitpaste defaulting to Yes instead of Maybe).
  • Changed conditionals from e.g. ifdef ARGSUPPORT to ifndef NOARGSUPPORT (makes compilation simpler).
2.0rc4
  • Fixed a rather silly bug wherein versions were printed as e.g. '2rc2' instead of '2.0rc2' (format was %.0f rather than %.1f).
2.0rc5
  • Eliminated a redundant realloc.
  • Added support for 'escalating' allocation (see below).
  • Added a 'trim' realloc to readfile (stdin section) to eliminate waste (chiefly when escalation has been compiled in) and maybe speed the program up on large data.
  • Added build manifest to --version.
2.0rc6
  • File-descriptor I/O. (compile with -DUSE_FD in the build command, after the version identifier.)
  • Added file locking. should be safer against operations by other processes.
2.0rc7
  • Argument parser is now much smarter. for one thing, you can now do 'clipboard <filename>' and it will figure you meant 'clipboard -c <filename>'.
  • Tightened up a switch in the argument parser - '-e' is no longer separate from '-v' and '-r'. no effect in the optimised builds, but debug builds should be slightly smaller.
  • Implicit pastes work properly now.
  • The build script now uses mkdir -p to avoid errors on Mac OS X systems that don't have a /usr/local/bin (I've read that these do exist).
2.0rc8
  • Changelog in top comment again (woops)
  • No-argsupport builds should be smaller (help and version functions are no longer compiled into those)
  • -s bufsize switch works properly now
  • No longer writes implicit newline after paste when the output file is not a tty
  • toclip emulation is now optional (define TOCLIPSUPPORT in the preprocessor to get it)
  • Help strings now properly morph when invoked as toclip (when toclip emulation is built)
2.0
  • Now using mmap to 'read' regular files
  • Translatenewlines uses a translation table or switch instead of if-else-if
  • Assorted hole-plugs
  • buildit is smarter about dealing with permissions WRT /usr/local/bin
  • buildit can use install destinations other than /usr/local/bin
  • buildit detects the absence of False and True (indicates Python 2.2.0) and compensates

Credits

Landon Fuller
for pointing out fcntl to me

2006-09-01 http://boredzo.org/clipboard/
Valid HTML 4.01!