Change the Printer Ready Message

Printer Job Language

Let's say you want to put your printer into Ghostbusters mode, reporting THERE IS NO PAPER ONLY ZUUL on its status panel. Or whatever you want it to say other than the boring READY. Let's see how to change what appears on the status panel display.

Hewlett-Packard developed PCL or the Printer Command Language starting in the mid 1980s. PCL has become a de facto industry standard. It started pretty simply as PCL 1, but by 1995 PCL 6 was an object-oriented page description language. It's like Postscript from a parallel universe.

PJL or Printer Job Language was introduced with the HP LaserJet IIIsi. It was created as an extension of PCL, and like PCL it has become a de facto standard that is supported by most Postscript printers. Well, kind of a standard. HP has formally defined a set of PJL commands. But an HP printer doesn't necessarily implement all of the documented PJL commands, and printers from HP and other manufacturers often implement proprietary commands not in the official PJL definition.

PJL handles job control, switching between printer languages, status querying, commands to manipulate the file system within the printer, plus what we're interested in here, the oddly named device attendance.

An older and more power-hunger HP LaserJet printer.

An HP LaserJet 4 printer eats a lot of electrical power. In the winter that simply provides useful heat. But in the summer, it might be a problem. Build a current-measuring box to see how much power your printer uses even when idle. Mine uses just 24 watts when truly idle, but about 790 watts when the fuser is running, meaning while it's printing and for 1-3 seconds from time to time during its "Ready" state.

First, let's use Nmap to run a port scan of the printer. I have replaced my vintage HP LaserJet 4 seen above with an HP LaserJet 4050tn, and I set up DNS records for it. The syntax is:

-sS Do a TCP SYN scan.
-sV Grab banners and handshake with each service in an attempt to figure out its version.
-O Try to figure out, or at least guess, the operating system. Note: That's dash-capital-Oh and not dash-zero.
hplj4050tn Use the printer's IP address if you don't have DNS fully set up.
[root@server src]# nmap -sS -sV -O hplj4050tn

Starting Nmap 6.47 ( ) at 2016-06-19 18:13 EDT
Nmap scan report for hplj4050tn (
Host is up (0.0021s latency).
rDNS record for
Not shown: 992 closed ports
21/tcp   open  ftp        HP JetDirect ftpd
23/tcp   open  telnet?
80/tcp   open  http       HP Jetdirect httpd
280/tcp  open  http       HP Jetdirect httpd
515/tcp  open  printer
631/tcp  open  http       HP Jetdirect httpd
5120/tcp open  tcpwrapped
9100/tcp open  jetdirect?
MAC Address: 00:30:C1:8B:D2:94 (Hewlett-packard)
Device type: print server|printer
Running: HP embedded
OS CPE: cpe:/h:hp:jetdirect_2591a cpe:/h:hp:laserjet_4050
OS details: HP JetDirect 2591A print server, HP LaserJet 4050 printer
Network Distance: 1 hop
Service Info: Device: print server

Notice that the printer accepts connections at TCP port 9100, that's where we need to send our PJL commands!

Download the program

Here is a Unix-family shell script. This works on my main Linux desktop and server, and on my OpenBSD laptop, and it should work on any Unix-family operating system as long as you have the nc command installed. If it isn't installed yet, it should be available as a package. If all else fails, you can build it from source code. Anyway, here is the script. Notice the highlighted characters:


# Check the user's syntax.
ERRMSG="Usage:  $0 <IP address or hostname> \"RDYMSG\""
if [ "$#" -lt 2 -o "$1" == "-h" -o "$1" == "--help" ]
	echo $ERRMSG
if [ "$#" -gt 2 ]
	echo "You may have omitted quotes around your message."
	echo ""
	echo "$ERRMSG
# How you tell nc to hang up after the file is sent
# varies from Linux to OpenBSD.
if [ "$(uname -s)" == "Linux" ]
	NCARGS="-q 0"
elif [ "$(uname -s)" == "OpenBSD" ]
	echo "Sorry, OS $(uname -s) not supported"

# Store a PCL message in a file.
# Generate escape char with: Ctrl-V Ctrl-Esc
cat > ${MSGFILE} << EOF
^[%-12345X@PJL RDYMSG DISPLAY="${2}"

# HP DirectJet talks on TCP port 9100.
# Send the file to that socket.
nc "${NCARGS}" $1 9100 < ${MSGFILE}

# Clean up
echo "Message sent, go check the printer display"
Or, just right-click and save this file

You can almost just copy and paste that script into a file, make it executable with chmod +x, and use it. But first you must change those two characters to Escape characters. Escape is ASCII 0x1b hexadecimal or 033 octal.

  1. Copy and paste the above into a file.
  2. Use vim to edit the file.
  3. Move the cursor to the first line now containing literal ^[.
  4. Place the cursor on the ^ character. Pressing 0 (zero) moves the cursor to the beginning of the line.
  5. Prepare to change two characters, the character under the cursor and the one to its right, by pressing: cl.
  6. Insert a literal Escape character by pressing four keys: Ctrl-V Ctrl-Escape
  7. Press Escape for good measure to make sure you are out of Insertion mode.

Now you're ready to change the "ready" message! Look at the display to see how many characters are available. This HP 4050tn has two rows of 16 characters for 25 or 32 characters total, and so we need to specify 5 spaces between "NO" and "PAPER":

$ hp-printer-msg hplj4050tn "THERE IS NO     PAPER ONLY ZUUL"
HP LaserJet printer displaying 'THERE IS NO PAPER ONLY ZUUL' as its ready message.
HP LaserJet printer displaying 'THERE IS NO PAPER ONLY ZUUL' as its ready message.
Part II
Part I


Yes, this says THERE IS NO PAPER ONLY ZUUL even when there is paper. When the printer runs out of paper, it tells me about that instead. This makes sense to me. Normally, Zuul rules the printer.

There are other messages, like OPMSG or Operator Message, and STMSG or Status Message, but sending one of them takes the printer offline.

The PCL/PJL Quick Reference Guide is 54 pages long, and Parts I and II of the PCL/PJL Technical Reference are 370 and 394 pages long, respectively.