AppleScript and standard input

What I like most about Unix is its depth. There’s always something more to learn. This morning, that highly sought after podcast guest Gabe Weatherhead linked to a cheat sheet by Peteris Krumins that summarized the input and output redirections available in bash. Most of them were familiar to me, but one made me sit up and take notice: a way of turning a string on the command line into the standard input for a command.

This is a useful trick when writing AppleScripts that use do shell script to run Unix utilities. AppleScript itself has no mechanism for creating standard input to feed to the commands do shell script calls. Apple, in this technical note, suggests using the echo command, which is what I did when writing my bbstdin utility a couple of weeks ago. But what I learned from the redirection cheat sheet, and from this earlier article, also by Peteris Krumins, was a more compact method.

The operator that does the conversion is <<<. It’s a relative of the more familiar (to me, at least) << operator. The << operator creates what are known as here documents, a way of creating a temporary, multi-line file-like object “right here.” Here documents are common in shell scripting, and the notation was adopted by Perl and other languages as a standard way of creating multi-line strings. The <<< variant is sometimes called a here string. It’s main use in shell scripting seems to be in creating single-line here documents.

But in AppleScript, it can be put to a more general use. For example,

applescript:
set a to "abcdef
ghijk
lmonp
qrstu
vwxyz"
do shell script "wc <<< " & quoted form of a

will yield

      5       5      31

which, if you’re not familiar with the output of the wc command, means “5 lines, 5 words, and 31 characters.”1 This is, I think, easier to understand than the equivalent

applescript:
set a to "abcdef
ghijk
lmonp
qrstu
vwxyz"
do shell script "echo " & quoted form of a & " | wc"

because it puts the command you really want to run at the beginning of the command string instead of burying it at the end.

One thing you might need to be careful with in using <<< is that it adds a linefeed to the end of the string. In the example above, there are actually only 30 characters in the original string, the 26 letters and 4 linefeeds. An easier example in which to see this is

applescript:
set b to "abcde"
do shell script "xxd <<< " & quoted form of b

The xxd command does a hex dump of its input, which in this case yields

0000000: 6162 6364 650a                           abcde.

The hex dump is in the middle section, after the colon. The 0a at the end of the hex dump is the ASCII code for the linefeed character, which was added by <<<.

If you’re a Perl programmer, you might wonder whether <<< is sort of like chomp in reverse—clever enough to add a linefeed only if there isn’t already one there. It isn’t. The output of

applescript:
set b to "abcde" & linefeed
do shell script "xxd <<< " & quoted form of b

is

0000000: 6162 6364 650a 0a                        abcde..

For most of my uses, the extra linefeed won’t matter, but it’s good to know that it’s there.

The advantage of having <<< in your toolbox is that it, like the echo trick, gives your AppleScripts the power of Unix’s text handling utilities as well as any Perl, Python, Ruby, or shell scripts you can write or find.


  1. OK, not characters, bytes. But when the string is all ASCII, as this one is, bytes and characters are interchangeable. ↩︎