iPhone and Linux

Friday, January 22, 2010

iPhone/Linux "Network Printing"

This hack may be useful if you have a non-network printer attached to your Linux box and want to print text remotely from your iPhone.

There are actually several ways to accomplish this. You can simply create a text file and scp that file to your linux box, or pipe it over ssh then execute a print command, but neither worked right for me. The first requires you to create the text file, put something in it, save, then send to print. As for the second method, I can't get text to pipe over ssh from my phone like it should, and even if I could, I'm not certain it would work with slogin and ssh keys. Nothing seemed to work for me, so I went with tapping an icon to automatically print the clipboard contents. This way, you don't have to fool with any files, and if you do want to print a file, you can open it, copy the text, and print it.

On the iPhone, you need PasteBoardStacker and ssh (preferrably set up with ssh keys). PasteBoardStacker is used because it's easy to get the plain text from it and I've never gotten around to decoding the Apple pasteboard. Maybe I'll tackle that one someday.

On your Linux box, you need a to be able to print from the command line, which should already be possible as long as your printer works. In my example, I also use enscript to format the text before piping the text to the lpr print command. Enscript should be present on most systems, and I can't imagine anyone actually prints text that isn't word wrapped.

Here is the script that goes on the phone. If you want to run it by tapping an icon on SpringBoard, you need to set up ssh keys and follow these directions. If you want to run it from MobileTerminal and type your ssh password in every time, change the scp line to "scp ispool USER@IP:/PATH/TO/PUT/FILE." This script can be named anything you like. (Update: I changed the first command, which was really long, to make two shorter lines)
#! /bin/sh
cd /var/mobile
text=$(awk 'BEGIN{ RS="</string>"}{gsub(/.*<string>/,"");print;exit}' $file | sed '
echo $text | tr -d  > ispool
scp -i ~/.ssh/KEYFILE ./ispool USER@IP:/PATH/TO/PUT/FILE
rm ispool
ssh USER@IP iprint

This goes on the Linux box and is called "iprint." If you want to name it something else, change "iprint" on the last line of the previous script to the new name. This uses enscript, but that's optional and you can change that whole line to "cat ispool | lpr" if you like.

#! /bin/sh
cat ispool | enscript -h -B -1 --word-wrap --media=A4
rm ispool

Or, if you would like a Prowl notification of the print job...
#! /bin/sh
cat ispool | enscript -h -B -1 --word-wrap --media=A4> tmpspool 2>&1
job=$(cat ispool)
output=$(cat tmpspool)
rm ispool tmpspool
curl -k https://prowl.weks.net/publicapi/add -F apikey=xxxxx -F application="Print job:" -F description="$output $job"

Update: I found that piping over ssh does work as it should. I don't know why it wasn't working for me the other day, except maybe because I was figuring out this whole print thing at 2 in the morning. That's what happens when you lay in bed and think "I'd like to print this out but don't want to get up." Anyway, this script can be ran on the phone to print the contents of the clipboard. I still like the above method because it allow me to get the output via Prowl notification, but this is simpler:
#! /bin/sh
text=$(awk 'BEGIN{ RS="</string>"}{gsub(/.*<string>/,"");print;exit}' $file

echo $text | tr -d  | slogin -i ~/.ssh/KEYFILE USER@IP lpr

Blog Archive