Tux

...making Linux just a little more fun!

2-cent tip: Automatically reenabling CUPS printer queues

René Pfeiffer [lynx at luchs.at]


Thu, 27 Dec 2007 16:05:23 +0100

Hello!

I have a short shell script fragment for you. It automatically reenables a printer queue on a CUPS printing server. CUPS takes different actions when a print job encounters a problem. The print server can be configured to follow the error policy "abort-job", "retry-job" or "stop-printer". The default setting is "stop-printer". The reason for this is not to drop print jobs or to send them to a printer that is not responding. Beginning with CUPS 1.3.x you can set a server-wide error policy. CUPS servers with version 1.2.x or 1.1.x cna only have a per-printer setting.

If you have a CUPS server an wish the print queue to resume operation automatically after they have been stopped, you can use a little shell script to scan for disabled printers (stopped printing queues) and reenable them.

#!/bin/sh
#
# Check if a printer queue is disabled and reenable it.
 
DISABLED=3D`lpstat -t | grep disabled | awk '{ print $2; }'`
 
for PRINTER in $DISABLED
do
        logger "Printer $PRINTER is stopped"
        cupsenable -h 127.0.0.1:631 $PRINTER && logger "Printer $PRINTER has been enabled."
done
This script can be executed periodically by crontab or by any other means.

Best, René.


Top    Back


Thomas Adam [thomas.adam22 at gmail.com]


Thu, 27 Dec 2007 17:54:19 +0000

Hello --

On 27/12/2007, René Pfeiffer <lynx@luchs.at> wrote:

What does this return? I am assuming a tokenised list of printers separated by whitespace? (It would have to be since you've not modified IFS anywhere...) Note though:

> DISABLED=`lpstat -t | grep disabled | awk '{ print $2; }'`
DISABLED="$(lpstat -t | awk '/disabled/ { print $2 }')"
I've always preferred writing such things where one makes -use- of their tools at hand, especially allowing awk to conditionally do the matching. No need for grep here. I also like $() for command substituion, and before anyone goes off on portability, I'll compromise with you: $() is nestable unlike backticks, and if you have a shell old enough not to understand $() you don't deserve to be using it in the first place. :P

> for PRINTER in $DISABLED

Quotes. Use more quotes:

for PRINTER in "$DISABLED"
-- Thomas Adam


Top    Back


Karolis Lyvens [karolisl at gmail.com]


Thu, 27 Dec 2007 21:33:42 +0200

On Thu, Dec 27, 2007 at 05:54:19PM +0000, Thomas Adam wrote:

> > DISABLED=`lpstat -t | grep disabled | awk '{ print $2; }'`
> 
> ``
> DISABLED="$(lpstat -t | awk '/disabled/ { print $2 }')"
> ''
> 
> I've always preferred writing such things where one makes -use- of
> their tools at hand, especially allowing awk to conditionally do the
> matching.  No need for grep here.  I also like $() for command
> substituion, and before anyone goes off on portability, I'll
> compromise with you:  $() is nestable unlike backticks,

Technically, backticks are nestable, but the nesting is extremely ugly, especially after 2 levels or so:

echo "`echo \`echo word \\\`echo foo \\\\\\\`echo bar\\\\\\\`\\\`\``"
> and if you have a shell old enough not to understand $() you don't
> deserve to be using it in the first place.  :P

In other words, $() is defined in POSIX, and, while there are shells that predate this standard, it is portable to every modern UNIX-like system (except Solaris, where /bin/sh is still pre-POSIX - I might be wrong, though).

> 
> > for PRINTER in $DISABLED
> 
> Quotes.  Use more quotes:
> 
> ``
> for PRINTER in "$DISABLED"
> ''

In this case, they are not relevant - word splitting is expected (and quotes prevent it from happening), because one is trying to iterate over words in the variable:

karolis@EN6350:~$ var="foo boo moo"
karolis@EN6350:~$ for entry in $var; do echo "$entry"; done
foo
boo
moo
karolis@EN6350:~$ for entry in "$var"; do echo "$entry"; done
foo boo moo
As you can see, when one is using quotes, then echo is called just once on the variable (and $entry is set to the entire contents of $var), which is not the desired behaviour.

-- 
Karolis Lyvens

Top    Back


Thomas Adam [thomas.adam22 at gmail.com]


Fri, 28 Dec 2007 00:48:05 +0000

On 27/12/2007, Karolis Lyvens <karolisl@gmail.com> wrote:

> In this case, they are not relevant - word splitting is expected (and
> quotes prevent it from happening), because one is trying to iterate over
> words in the variable:

Quite. I meant to quote PRINTER further down.

-- Thomas Adam


Top    Back


René Pfeiffer [lynx at luchs.at]


Thu, 27 Dec 2007 20:46:56 +0100

On Dec 27, 2007 at 1754 +0000, Thomas Adam appeared and said:

> Hello --
> On 27/12/2007, René Pfeiffer <lynx@luchs.at> wrote:
> What does this return?  I am assuming a tokenised list of printers
> separated by whitespace?

Yes, this was the idea, and it did just that after some tests.

> Note though:
> > DISABLED=3D`lpstat -t | grep disabled | awk '{ print $2; }'`
> ``
> DISABLED=3D"$(lpstat -t | awk '/disabled/ { print $2 }')"
> ''
> I've always preferred writing such things where one makes -use- of
> their tools at hand, especially allowing awk to conditionally do the
> matching.

That's a good idea. I think you just upgraded the little script to version 0.2. :-) CUPS before 1.3.x not having a global error policy is something that bothers me more.

Best, René.


Top    Back