Mixing Terminal with GUI apps

It’s not laziness, it’s just that we get stuck in a rut. When working in Terminal, your hands are over your keyboard, and you type commands. When working in GUI apps, your hand spends more time on the mouse or trackpad, and you don’t type commands. But in macOS, some of the most powerful and efficient actions are those which get the best out of the command line and apps, together.

This article looks at some of the ways that you can move data between the different worlds of Terminal and GUI apps.

Files

The most basic, general, and clumsy way to move data between Terminal and apps, in either direction, is using files. Let’s say that I’m writing some documentation and want to include a listing from the ls -la@ command. If I push the command output into a text file using
ls -la@ > file.txt
then I can open file.txt, copy and paste its contents into my documentation.

It’s worth pausing for a moment here to consider the different ways that the command line supports the transfer of data like this. You can pipe output from one command to another using
command1 | command2

If you want to push the output from a command to a text file, there are two simple options
command1 > file.txt
which overwrites the contents of file.txt, and
command1 >> file.txt
which appends output to file.txt.

Matching those,
command1 < file.txt
pulls input for command1 from file.txt

These are good fallbacks, but when you want to move a chunk of text from one GUI app to another, you don’t save it as a file and use that as an intermediary, you copy it to…

The clipboard

The command line in macOS has direct access to the system clipboard, which can save you messing around with text files. The two commands which do this are pbcopy and pbpaste; both are very old and don’t quite behave as you might expect them to after reading their man pages.

To solve the problem above, I simply pipe the output of the ls command to the clipboard using
ls -la@ | pbcopy
switch to the GUI app in which I’m editing the documentation, and paste that text in. You can do this with all sorts of other command output, such as
history 40 | pbcopy
which copies the last forty commands in Terminal (including the history command itself) to the clipboard. You can also copy straight from a file, as in
pbcopy < file.txt
which copies the whole of file.txt to the clipboard, something which can be hard to do in many apps.

This is straightforward when working with text files, but gets more involved when using other file formats. pbcopy recognises RTF and EPS files, which it copies in their original formats, but all others, such as PNG graphics files, are copied as text, which makes them pretty useless with other apps. Try pasting that graphics file, and it’s no longer recognisable as a PNG file, just a whole bunch of binary in a text string.

Its matching command to paste in Terminal, pbpaste, is also quite constrained in its usefulness. Copy a chunk of text in an app, then type
pbpaste > file.txt
and that copied text is pasted into the text file file.txt. But that doesn’t appear to work with RTF content, and any PNG graphic is mutated into unusable binary-text.

According to the man page, you can use the option -Prefer rtf (or txt, or ps) to force pbpaste to use RTF, text, or EPS versions when they’re held in the clipboard, but at present that doesn’t seem to do anything to help the problem of pasting to an RTF file. The man page for both pbcopy and pbpaste also claims that you can select any of the four system clipboards using an option like -pboard find, but that doesn’t seem to do anything useful any more.

When you can use them, pbcopy and pbpaste are much better ways of moving content between the very different worlds of Terminal and GUI apps.