Printing system

From Unix Wiki
Jump to: navigation, search

Generic

Print server communication protocols

LPD : 515
JetDirect : 9100
IPP : 631
SMB : 445

CUPS

Add print queue

lpadmin -p Name -v lpd://10.0.0.1/Name -m postscript.ppd.gz -E
lpadmin -p Name -v socket://10.0.0.1:9100 -m raw -E

Basic CUPS Tips

Printers stats:

lpstat -s [printer]
  Status summary. Shows where the actual device resides. 
lpstat -o [destination] 
  Shows the jobs queue on the specified destinations.
lpstat -p [printer]
  Enable or not the requested printer.
lpq -p [destination]
  Printer info
lpq -al
  Jobs on all printers

Administration:

lp -i [job-id] -H restart
  Resend particular job to device.

Configuration:

lpadmin
 CLI Printer configuration utility

List available PPDs

lpinfo -m

Show number of queued jobs for all queues

lpstat -o | awk '{print $1}' | sed -e 's/-[0-9]*$//g' | sort | uniq -c

Show total print job size per printer

for PRINTER in `lpstat -o | awk '{print $1}' | sed -e 's/-[0-9]*$//g' | sort | uniq` ; do echo -n "${PRINTER} " && lpstat -o${PRINTER} | awk '{sum += $3} END {print sum, "total"}' ; done

Get list of devices for printers which are not in 'idle' state

lpstat -p | grep -v idle | grep since | awk '{print $2}' | while read line ; do lpstat -s | grep $line ; done

Backup printer configurations

tar czpfv ~/cups-`date +%F`-`hostname -s`.bak.tar.gz /etc/cups /etc/alchemist

CUPS test page

lp -d noprint /usr/share/cups/data/testprint.ps

Oracle DB concurrent printers

Oracle printers reside on MT node. You can see concurrent processes with the following command.

ps -ef | grep FNDLI | cut -f1 -d' ' | sort u

HP-UX

All HP printers use JetDirect.

Configuration files:

/etc/lp/interface/[fname]
  Where [fname] is a name of a queue

To find out where device resides on the net, use

grep ^PER /etc/lp/interface/[queue]

To disable jobs:

lpstat -o[queue] | grep ^[queue] | cut -f1 -d' ' | while read n; do cancel $n; done


Solaris

Enable debugging

http://docs.oracle.com/cd/E19082-01/819-7761/gekzo/index.html

Please note there should be a tab in first line before '/var'

echo "lpr.debug /var/tmp/lpr.debug" >>/etc/syslog.conf
touch /var/tmp/lpr.debug
svcadm restart system-log

Basic actions with print service

To check scheduler state

# lpstat -r 

Check print service state

# svcs -a | grep print 

Restart print services

# svcadm enable svc:/application/print/server:default
# svcadm disable svc:/application/print/server:default

Use Solaris OS Print Manager

# /usr/sbin/printmgr &

Add queue

lpadmin -p printer1 -s lpd://server/printers/queuename -D "Description" -u allow:all

Add using JetDirect

# lpadmin -x QueueName
# lpadmin -p QueueName -v /dev/null -m netstandard
# lpadmin -p QueueName -T unknown -I any
# lpadmin -p QueueName -o protocol=tcp -o dest=10.10.10.10:9100
# /usr/bin/enable QueueName
printer "QueueName" now enabled
# /usr/sbin/accept QueueName
destination "QueueName" now accepting requests
# lpadmin -p QueueName -o banner=never

Ask print server directly

LPD

  1. Telnet to port 515 of printserver;
  2. Press ^D;
  3. Type name of print queue;
  4. Press ENTER.

Next script will do exactly the same thing.

Simple perl script to request stats of a printer directly from a print server.

#/usr/bin/env perl

if ($#ARGV <0){
	print "\nUsage: lpdstatus.pl LPDSERVER [QUEUE]\n";
	exit 1;
}

use IO::Socket;
$server = $ARGV[0];
$queue = $ARGV[1];
my $sock = new IO::Socket::INET ( 
	PeerAddr => $server,
	PeerPort => '515',
	Proto => 'tcp',
	Timeout => 15,
); 
die "lpdstatus> Error: Could not create socket: $!\n" unless $sock; 

sub print_answer
{
    printf("lpdstatus> Recieved answer: %s bytes.", length(join("",@_)));
    print("================");
    printf("%s", join("",@_));
    print("================\n");
}


$command = sprintf ("%c%s\n", 4, $queue);
printf $sock $command; 
        # Read response from server and format
        eval {
                local $SIG{ALRM} = sub { die "timeout\n" };
                alarm 15;
                while (<$sock>) {
                        push(@qstatus, $_);
                }
                alarm 0;
                1;
        };


    if( $@ )
    {

	print_answer @qstatus;
	printf("lpdstatus> Error: timed out reading from %s\n", $server)
            if( $@ =~ /timeout/ );

    }else{
	print_answer @qstatus;
	printf("lpdstatus> Exiting sucessfully.\n");
    }


close($sock);

https://non7top.googlecode.com/svn/trunk/scripts/lpdstatus/lpdstatus.pl

JetDirect

Troubleshooting

Test PostScript page for Duplex

$ cat duplextest.ps
%!
<</Duplex true>> setpagedevice
/Times-Roman findfont
20 scalefont
setfont
newpath
72 72 moveto
(duplex page 1) show
clippath stroke showpage
newpath
72 72 moveto
(duplex page 2) show
clippath stroke showpage

Script PDF to PS + DUPLEX

#!/bin/sh

# Setting variables
OutFile=$1
InFile=$2
SHLIB_PATH=/usr/local/lib

# Convert PDF to PostScript
/usr/bin/gs.sh -q -dNOPAUSE -dBATCH -sDEVICE=pswrite -dLanguageLevel=2 -sPAPERSIZE=letter -dFIXEDMEDIA -sOutputFile=${InFile}.ps ${FND_TOP}/resource/offsetfix.ps ${InFile}

# Inserting duplex PS codes in converted postscript file
sed '/%%BeginResource/ a\
<< /Duplex true /Tumble false >> setpagedevice' \
${InFile}.ps > ${OutFile}
 
# Cleaning temp files
if [[ -r ${InFile}.ps ]]; then
rm ${InFile}.ps
fi

Parsing CUPS error log

This script will parse provided cups error_log file and generate table with jobs print times or if you need with difference between start and complete of print job in seconds.

#!/usr/bin/perl
=head
    Script for parsing CUPS error_log
=cut

use strict;
#use warnings;
use Getopt::Long ();
use Time::Local;
use Switch;


use constant RESARGS        => 100; # - illegal arguments

my %mth = qw(Jan 0 Feb 1 Mar 2 Apr 3 May 4 Jun 5 Jul 6 Aug 7 Sep 8 Oct 9 Nov 10 Dec 11);
my %opts;
my %jobs;
my %sizes;
my $timestamp;
my $job;
my $action;
my $size;

#see usage() for argument's descriptions
Getopt::Long::GetOptions( 'file=s' => \$opts{'f'},
                'diff' => \$opts{'d'},
                'help' => \$opts{'h'},
                'size' => \$opts{'s'},
) or usage(RESARGS);

usage($opts{'h'} ? 0 : RESARGS) if( $opts{'h'} || !$opts{'f'} );
if ( $opts{'s'} ) {
    my @lpstat = `lpstat -W completed -o`;
#    my @lpstat = `cat lpstat.out`;  # Debug
    foreach my $line ( @lpstat ) {
        $line =~ m|^\S+?-(\S+?)\s+\S+?\s+(\S+?)\s|;
        $job = $1;
        $size = $2;
        $sizes{"$job"}->{"SIZE"} = $size;
    }
}
open my $fh, "< $opts{'f'}" or die "Error opening file $opts{'f'}: $!\n";
while (<$fh>) {
    if (!/\[Job/) {next;}  # Next if working string doesn't contain "[Job"
    chomp;
    $_ =~ m|^. \[(\S+?) \S+?] \[Job (\S+)\](.*$)|;  # Match string
    $timestamp = $1;
    $job = $2;
    $action = $3;
#    print "$_\n$job\t$timestamp\t$action\n";  # Debug
    # Converting timestamp into Unix time format
    my @t = split(/:/,$timestamp);
    my @d = split( /\//,shift( @t) );
    my @Htime = (reverse(@t),$d[0],$mth{$d[1]},$d[2] - 1900);
    my $ltime = timelocal(@Htime);
    ###
    switch ($action) {
        case /Adding start/              { $jobs{"$job"}->{"STARTED"} = $ltime }
        case /Queued on/                 { $jobs{"$job"}->{"QUEUED"} = $ltime ; $jobs{"$job"}->{"PRINTER"} = $1 if $action =~ m|"(\S+?)"|; }
        case /Completed successfully./   { $jobs{"$job"}->{"COMPLETED"} = $ltime }
    }
}
close $fh;

# Printing result table
print "JOB\tSTARTED\tQUEUED\tCOMPLETED\tPRINTER\tSIZE\n";
# Split into two loops just for speed
if ( $opts{'d'} ) {
     foreach $job (keys %jobs) {
          print "$job\t", $jobs{"$job"}->{"STARTED"}, "\t",
                 $jobs{"$job"}->{"QUEUED"}-$jobs{"$job"}->{"STARTED"}, "\t",
                 $jobs{"$job"}->{"COMPLETED"} == '' ? -1 : $jobs{"$job"}->{"COMPLETED"} - $jobs{"$job"}->{"STARTED"}, "\t",
                 $jobs{"$job"}->{"PRINTER"}, "\t",
                 $sizes{"$job"}->{"SIZE"}, "\n";
     }
} else {
     foreach $job (keys %jobs) {
         print "$job\t", $jobs{"$job"}->{"STARTED"}, "\t",
                         $jobs{"$job"}->{"QUEUED"}, "\t",
                         $jobs{"$job"}->{"COMPLETED"} == '' ? -1 : $jobs{"$job"}->{"COMPLETED"}, "\t",
                         $jobs{"$job"}->{"PRINTER"}, "\t";
                         $sizes{"$job"}->{"SIZE"}, "\n";
     }
}

sub usage {
    print STDOUT << "USAGE";
Usage: $0 -f FILENAME [-d]
    -f, --file         - file name for parsing
    -d, --diff         - print time difference instead of absolute time values
    -s, --size         - collect print job size if available using lpstat command
    -h, --help         - this help output
USAGE
    exit $_[0];
}

exit 0;

Sample ZPL file

Wil print word ZEBRA and some barcode.

^XA
^LH30,30
^FO20,10^AD^FDZEBRA^FS
^FO20,60^B3N,Y,20,N^FDAAA001^FS
^XZ

Links