[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home] [volume] [parte]


Capitolo 212.   Stampa

Tradizionalmente, il dispositivo di stampa permette solo la scrittura, cioè si comporta come un file al quale si possono solo aggiungere dati. In questa situazione, la stampa si ottiene semplicemente trasferendo (copiando) un file alla stampante. Naturalmente, il file deve essere stato predisposto in modo da poter essere interpretato correttamente dalla stampante che si utilizza.

Quando si ha la necessità di applicare una trasformazione al file da stampare, prima che questo raggiunga la stampante, si utilizza normalmente un filtro di stampa, cioè un programma o uno script che può essere inserito in un condotto. I filtri di stampa vengono quindi utilizzati sia per adattare i file da stampare alle caratteristiche particolari della stampante che si ha a disposizione, sia per ottenere degli effetti, come l'aggiunta di intestazioni.

Esistono nel mercato delle stampanti che non si accontentano di ricevere un file per iniziare a stampare, ma richiedono l'utilizzo di un protocollo di comunicazione, che spesso è mantenuto segreto. Queste stampanti, per funzionare, hanno bisogno della presenza di un programma speciale, predisposto dalla casa produttrice; pertanto non sono compatibili in alcun modo con i sistemi GNU. Si tratta in particolare delle stampanti che utilizzano il cosiddetto Windows printing system. Si deve fare attenzione quindi, prima di acquistare una stampante da usare con un sistema GNU.

Questa parte del documento, dedicata alla stampa, fa riferimento a concetti che possono essere chiariti solo più avanti, come la stampa remota e l'utilizzo di strumenti grafici. Sotto questo aspetto, l'argomento dovrebbe essere trattato più tardi; tuttavia, dal momento che l'esigenza di stampare si avverte molto presto, l'argomento viene anticipato. Pertanto, chi ha l'esigenza di realizzare un servente di stampa in grado di ricevere richieste da una rete, se non è già informato su queste cose, deve attendere e leggere una serie di capitoli sul TCP/IP nel volume X.

Per poter utilizzare la stampante con un sistema GNU/Linux, occorre avere compilato il kernel inserendo la gestione delle porte di comunicazione necessarie e della stampa stessa.

212.1   Dispositivi e stampa brutale

I file di dispositivo associati alla stampa, in un sistema GNU/Linux, dipendono dal tipo di porta di comunicazione utilizzato. A titolo di esempio, la prima stampante collegata su porta parallela dovrebbe essere accessibile attraverso il file di dispositivo /dev/lp0, mentre alla prima stampante collegata a un bus USB si associa di solito il file /dev/usb/lp0.

Eventualmente, si può controllare con il comando seguente:

dmesg | less[Invio]

Dal risultato che si ottiene, si deve cercare una riga simile a quella seguente:

lp0: using parport0 (polling)

L'utente root può utilizzare direttamente il dispositivo di stampa copiando su di esso il file che vuole stampare:

cp stampa.prn /dev/lp0[Invio]

Si tratta comunque di un modo di utilizzo della stampante decisamente sconsigliabile o quantomeno da riservare a circostanze particolari. Un'azione del genere corrisponde a quello che in ambiente Dos si può fare nel modo seguente:

C:> COPY /B STAMPA.PRN LPT1:[Invio]

212.2   Visione generale e astratta

Il sistema di stampa tipico si avvale di una coda, ovvero di un deposito in cui accodare i file da inviare alla stampante. Di solito, il programma che si occupa di inserire il file da stampare nella coda non fa altro: per inviare questi file alla stampante c'è un demone apposito che attende di vedere qualcosa nella coda (figura 212.2).

Figura 212.2. Coda di stampa in un sistema locale chiuso.

collegamenti

Quando il sistema di stampa gestisce anche le stampe remote, si introduce un protocollo di comunicazione e, assieme a questo, anche qualche problema in più. Dal lato dell'elaboratore che offre il servizio ci deve essere un demone in grado di ricevere queste richieste di stampa, con il compito di accodare tali stampe nel proprio sistema (figura 212.3).

Figura 212.3. Coda di stampa in un sistema che riceve richieste dall'esterno, attraverso la rete.

stampa coda rete

Per inviare una richiesta di stampa a un elaboratore remoto, ci possono essere due tipi di approcci. Nella situazione più semplice, un programma potrebbe provvedere da solo a ricevere il file da stampare e a instaurare la connessione con il nodo di rete remoto al quale questo deve essere rinviato per la stampa; in alternativa, potrebbe essere la stessa coda di stampa locale che si occupa di rinviare la stampa a un nodo di rete remoto (figura 212.4).

Figura 212.4. Trasmissione delle stampe a un nodo di rete remoto.

stampa trasmissione remota

Spesso, molte funzionalità sono raggruppate assieme in uno stesso programma, o in uno stesso demone. Per esempio, è normale che il demone che si occupa di provvedere alla stampa di ciò che trova nella coda, sia anche in grado di ricevere una richiesta di stampa dall'esterno, provvedendo da solo ad accodarla, ed è normale che lo stesso demone sia in grado di instaurare una connessione con un altro servizio di stampa remoto quando deve demandare la stampa a quel sistema.

212.2.1   Problemi collegati con la stampa remota

La stampa remota introduce tanti piccoli problemi e spesso si deve penare un po' prima di arrivare al risultato. Per prima cosa è necessario che ci sia accordo tra il programma che invia una richiesta di stampa e quello che deve riceverla, cosa questa che riguarda la coerenza con i protocolli relativi. Tuttavia, il protocollo standard che esiste attualmente è insufficiente per le esigenze reali (RFC 1179) e ogni sistema di stampa introduce le sue estensioni più o meno incompatibili con gli altri.

Quando un sistema offre un servizio attraverso la rete, come nel caso di un servente di stampa, si pone il problema di non accettare tutte le richieste incondizionatamente e di stabilire chi sia abilitato ad accedere. In pratica, occorre autenticare gli accessi. Questo problema non è previsto dal protocollo citato e il sistema di stampa che vuole essere compatibile con tutto, può solo limitarsi a selezionare gli accessi in base alla loro origine.

L'ultimo problema da considerare è legato al fatto che con la stampa remota si fanno transitare le informazioni relative attraverso la rete, rischiando l'intercettazione di informazioni che potrebbero essere delicate. Un sistema di stampa evoluto potrebbe prevedere la cifratura di queste comunicazioni, introducendo una propria estensione al protocollo standard.

212.2.2   Filtri di stampa

Nel momento in cui si considera che per stampare si prepara un file e lo si invia alla stampante, per gestire stampanti di tipo diverso in modo trasparente, basta realizzare dei programmi filtro appositi con lo scopo di rielaborare i dati nel modo più opportuno prima di passarli effettivamente alla stampante.

Questi programmi filtro potrebbero essere inseriti in diversi punti della catena di un sistema di stampa; in particolare si potrebbe scegliere se questa elaborazione deve avvenire prima dell'inserimento nella coda di stampa, o se questo debba avvenire dopo. Di solito, i file vengono messi nella coda così come sono, ed è il demone di stampa che si occupa di farli rielaborare da un programma filtro adatto (figura 212.5).

Figura 212.5. Introduzione di un filtro in un sistema di stampa tipico.

stampa con filtro

Tuttavia, occorre considerare che si possono fare delle acrobazie imprevedibili per un principiante, per cui la distinzione non diventa più tanto netta. Infatti, capita a volte che il programma filtro prenda i dati e non restituisca nulla, o meglio, invece di restituire qualcosa nel modo previsto, potrebbe farci qualcosa di diverso (si vede la sezione 212.2.4 e la figura 212.6).

212.2.3   Stampanti virtuali multiple

Un sistema di stampa come descritto astrattamente in queste sezioni, potrebbe essere in grado di gestire code differenti, senza che questo implichi la disponibilità effettiva di più stampanti collegate allo stesso elaboratore. Dal punto di vista del sistema di stampa, queste code sono delle stampanti «virtuali» collegate in qualche modo a delle stampanti reali.

Per fare un esempio pratico, un sistema di stampa potrebbe essere stato configurato in modo da avere due code di stampa: per una stampante locale per una stampante remota. In questo modo, quando si richiede di stampare utilizzando una coda, si ottiene alla fine la stampa attraverso la propria stampante locale, mentre utilizzando l'altra, si ottiene l'invio di una richiesta di stampa a un sistema remoto.

Le possibilità non si limitano a questo; per esempio le code potrebbero essere state distinte perché a ognuna di queste viene attribuito un filtro di stampa diverso, di solito per permettere di utilizzare una stampante differente da quella solita. Per esempio, si potrebbe avere la coda denominata lp per la stampa diretta senza filtri; la coda lp-lj da utilizzare quando si collega una stampante HP Laserjet o compatibile; la coda lp-ps da utilizzare quando si collega una stampante PostScript.

212.2.4   Quando il meccanismo dei filtri non funziona bene

In precedenza è stato mostrato lo schema di un sistema di stampa che permette l'inserimento di un filtro prima di arrivare alla stampante. Si è accennato anche al fatto che il demone che legge la coda, mandando i dati al filtro, potrebbe essere difettoso e non essere in grado di rileggere ciò che restituisce il filtro stesso. In questi casi, che sono capitati effettivamente, si può attuare un rimedio, apparentemente un po' strano: il programma filtro, invece di restituire il risultato della sua elaborazione attraverso lo standard output, lo invia in un'altra coda di stampa, per la quale non è previsto alcun filtro (figura 212.6).

Figura 212.6. Quando il meccanismo del filtro è zoppicante.

stampa con filtro a senso unico

Riprendendo l'esempio già descritto in precedenza, in cui la coda denominata lp è prevista per la stampa diretta senza filtri e la lp-lj è fatta per stampare attraverso una stampante HP Laserjet o compatibile, il filtro abbinato a questa seconda coda, potrebbe semplicemente inviare il risultato della sua elaborazione nella coda di stampa normale, lp, che non avendo filtri non ha alcun problema.

212.3   Sistema di stampa BSD o compatibile

Nei sistemi Unix non esiste un sistema di stampa «standard» per vari motivi, a cominciare dal fatto che i pochi riferimenti disponibili hanno caratteristiche insufficienti rispetto alle esigenze attuali. Bene o male, i comandi per la stampa tendono a imitare il comportamento del sistema di stampa BSD, ovvero il lavoro di Berkeley. (1) Alcune distribuzioni GNU/Linux utilizzano proprio il sistema BSD, altre preferiscono qualcosa di più potente che gli assomiglia vagamente. In generale, non è il caso di approfondire questo o quel sistema di stampa, proprio perché si tratta di una materia in evoluzione, a meno che ci siano delle esigenze particolari, nel qual caso si possono studiare le pagine di manuale o la documentazione che accompagna il sistema di stampa che offre la propria distribuzione GNU.

Figura 212.7. Coda di stampa in stile BSD.

stampa coda bsd

Come si può vedere nella figura 212.7, il sistema di stampa in stile BSD si avvale del programma lpr per accodare le stampe e del demone lpd per gestire la stampa di ciò che è stato accodato, oltre che per ricevere le richieste attraverso la rete. Fa parte della tradizione anche il file di configurazione /etc/printcap, nel quale vengono definite le varie code di stampa, a cui si possono abbinare o meno dei filtri opportuni.

212.3.1   Configurazione con «/etc/printcap»

La configurazione di un sistema di stampa in stile BSD avviene principalmente attraverso il file /etc/printcap, con il quale si definiscono le code di stampa e il loro comportamento. Il suo contenuto è organizzato in record, dove ognuno di questi contiene le informazioni relative a una coda. I campi di questi record sono separati da due punti verticali (alle volte doppi e altre singoli) e possono essere spezzati su più righe, utilizzando la barra obliqua inversa (\) seguita immediatamente dal codice di interruzione di riga. Si osservi il fatto che l'ultimo campo è concluso da due punti.

campo_1:campo_2:...:campo_n:
campo_1:\
    :campo_2:\
    :campo_3:\
    ...
    :campo_n_1:\
    :campo_n:

Il sistema di stampa BSD originale richiede il simbolo di continuazione delle righe nel caso i record vengano spezzati, mentre altri sistemi compatibili, potrebbero farne a meno. In generale, è sempre meglio indicare la continuazione, anche se ciò non dovesse servire.

All'interno di questo file si possono trovare le indicazioni di code differenti che si riferiscono a un'unica stampante reale, per esempio quando si utilizzano configurazioni multiple per la stessa unità fisica.

Si osservi che il simbolo # rappresenta l'inizio di un commento, con il quale, il testo che segue fino alla fine della riga non viene tenuto in considerazione; nello stesso modo vengono ignorate le righe vuote e quelle bianche.

Viene mostrato subito un esempio, il cui contenuto viene poi descritto gradualmente in questa sezione:

# Stampante predefinita
lp|laserjet|HP Laserjet:\
        :sd=/var/spool/lpd/lp:\
        :mx#0:\
        :sh:\
        :lp=/dev/lp0:\
        :if=/var/spool/lpd/lp/filtro:

# Stampa di testo
ascii:\
        :sd=/var/spool/lpd/tx:\
        :mx#0:\
        :sh:\
        :lp=/dev/lp0:\
        :if=/var/spool/lpd/ascii/filtro:

# Stampa diretta senza filtri
bare:\
        :sd=/var/spool/lpd/bare:\
        :mx#0:\
        :sh:\
        :lp=/dev/lp0:

# Stampante condivisa dell'elaboratore weizen.mehl.dg
net:\
        :sd=/var/spool/lpd/net:\
        :mx#0:\
        :sh:\
        :rm=weizen.mehl.dg:\
        :rp=lp:\
        :if=/var/spool/lpd/net/filtro:

Il primo campo di ogni record identifica tutti gli pseudonimi possibili di una certa coda di stampa, solitamente per identificare anche la stampante a cui la coda è abbinata. Questi sono separati da una barra verticale. Gli altri campi contengono tutti una sigla identificativa composta da due caratteri, seguita eventualmente da un valore che gli viene attribuito.

nome_coda[|nome_stampante]...:{sigla_campo[assegnamento]:}...

La presenza di queste sigle permette in pratica di avere un numero variabile di campi, con un ordine variabile, dove solo il primo ha un ruolo prestabilito: quello di identificare la coda.

Nel preparare questo file è molto importante fare bene attenzione a non lasciare spazi di qualunque tipo dopo i simboli di continuazione (\), altrimenti questi simboli verrebbero intesi solo come una sequenza di escape che conferma il valore letterale del carattere che segue e non ci sarebbe alcuna continuazione. Questa considerazione è importante, perché poi è difficile scoprire errori del genere.

Il sistema di stampa BSD tradizionale prevede una quantità molto grande di campi nei record di /etc/printcap. Le esigenze attuali sono tali per cui i campi che si utilizzano in pratica sono molto pochi e non vale la pena di approfondire tecniche ormai superate, riferite a campi che in alcuni sistemi derivati potrebbero anche non essere più disponibili. La tabella 212.9 riepiloga i campi più comuni.

Tabella 212.9. I campi più importanti dei record che compongono il file /etc/printcap.

Campo Significato Descrizione
if
Input filter Filtro di ingresso.
lf
Log file File per la registrazione degli errori.
af
Account file File per la registrazione della contabilità.
lp
Line printer File di dispositivo di stampa.
mx
Max Dimensione massima di una stampa.
pl
Page length Altezza della pagina in righe.
pw
Page width Larghezza della pagina in caratteri.
pc
Price Prezzo per pagina.
rm
Remote machine Nodo di rete remoto per la stampa.
rp
Remote printer Coda di stampa remota.
sd
Spool directory Directory usata per la coda.
sf
Suppress feed Soppressione dell'avanzamento di separazione.
sh
Suppress header Soppressione dell'intestazione.

I campi possono servire a indicare informazioni di tipo diverso e a seconda di questo cambia il modo con cui i dati relativi sono indicati:

Campo Descrizione
if=filtro_di_ingresso
Indica il percorso assoluto del programma, o dello script, che serve come filtro dei dati in ingresso. Il programma o lo script in questione deve essere in grado di ricevere i dati dallo standard input e di emettere il risultato attraverso lo standard output.
lf=file_delle_registrazioni
Permette di specificare il percorso assoluto di un file da utilizzare come registro degli eventi importanti che riguardano la stampa. In generale serve per annotare gli errori.
lp=file_di_dispositivo
È indispensabile e serve a indicare il file di dispositivo corrispondente alla porta presso cui è connessa la stampante.
mx#n
Indica la dimensione massima (in multipli di 1 024 byte) di un file di stampa. Di solito, questo campo viene indicato con il valore zero (mx#0), per non porre alcun limite di dimensione.
rm=nodo
Indica un nodo di rete a cui ci si deve connettere per richiedere la stampa.
rp=nome_coda_remota
Si utilizza in abbinamento con il campo rm, allo scopo di indicare esplicitamente il nome della coda di stampa remota.
sd=directory_contenente_la_coda
Indica il percorso della directory da utilizzare per la gestione di questa coda. In linea di principio, dovrebbe essere possibile usare una sola directory per più code di stampa, al contrario di quanto si vede nell'esempio introduttivo.
sf
È un campo booleano che, se presente, elimina l'avanzamento della carta alla fine di ogni processo di stampa.
sh
È un campo booleano che, se presente, elimina l'emissione dell'informazione sul programma cliente che ha richiesto la stampa, nella pagina di intestazione (ovvero di separazione) tra un processo di stampa e il successivo. Se viene usato in combinazione con sf, viene eliminata completamente la pagina di separazione.

Di seguito vengono descritte alcune porzioni dell'esempio introduttivo.

bare:\
        :sd=/var/spool/lpd/bare:\
        :mx#0:\
        :sh:\
        :lp=/dev/lp0:

La voce bare indica semplicemente le informazioni seguenti:

La cosa importante da notare in questo tipo di definizione è che non è stato indicato un filtro per i dati. Ciò significa che i dati da inviare alla stampante non subiscono trasformazioni; infatti, il nome bare è stato scelto opportunamente.

lp|laserjet|HP Laserjet:\
        :sd=/var/spool/lpd/lp:\
        :mx#0:\
        :sh:\
        :lp=/dev/lp0:\
        :if=/var/spool/lpd/lp/filtro:

Questo record del file /etc/printcap è più complesso. Per prima cosa si nota che è possibile fare riferimento a questo utilizzando tre nomi possibili: lp, laserjet o HP Laserjet. A parte questo, si nota l'inserimento di un filtro di ingresso. Il file /var/spool/lpd/lp/filtro potrebbe essere un programma o uno script che esegue un qualche tipo di trasformazione sui dati ricevuti.

net:\
        :sd=/var/spool/lpd/net:\
        :mx#0:\
        :sh:\
        :rm=weizen.mehl.dg:\
        :rp=lp:\
        :if=/var/spool/lpd/net/filtro:

Questo esempio rappresenta un record del file /etc/printcap che dichiara l'utilizzo di una stampante remota. La differenza sta quindi nel fatto che il campo lp è assente e al suo posto si utilizzano rm e rp per indicare rispettivamente il nome dell'elaboratore remoto (weizen.mehl.dg) e il nome della coda presso l'elaboratore remoto.

Quando si utilizza una stampante remota, nel caso in cui i dati da stampare richiedano un'elaborazione attraverso un filtro, occorre decidere se tale elaborazione debba avvenire prima dell'invio, o alla destinazione. In questo caso, viene indicato un filtro attraverso il campo if: probabilmente, la coda corrispondente al nome lp dell'elaboratore remoto non ha un filtro adatto.

212.3.2   Servizio di stampa

Il servizio di stampa nel sistema derivato da BSD è gestito dal demone lpd. Questo si occupa principalmente di scandire le code e di mettere in stampa ciò che vi dovesse trovare. È anche in grado di ricevere richieste di stampa attraverso la rete, occupandosi di metterle in coda; infine, è anche capace di inviare una richiesta di stampa a un nodo di rete remoto.

In condizioni normali, lpd non richiede argomenti nella riga di comando; comunque, la sintassi degli argomenti di lpd è molto diversa da un sistema all'altro.

Ogni sistema di stampa utilizza le proprie tecniche di autorizzazione per concedere l'accesso al servizio di stampa. In generale, un sistema di stampa installato attraverso i pacchetti della propria distribuzione GNU/Linux dovrebbe consentire la stampa quando questa è richiesta a partire dallo stesso elaboratore locale; mentre per consentire l'accesso dall'esterno, occorre predisporre altri file di configurazione che non sono standard.

Di solito, il servizio di stampa viene avviato e arrestato attraverso uno script della procedura di inizializzazione del sistema, che potrebbe assomigliare all'esempio seguente:

#!/bin/sh

test -f /usr/sbin/lpd || exit 0

case "$1" in
  start)
        echo -n "Avvio del servizio di stampa: "
        /usr/sbin/lpd
        echo
        ;;
  stop)
        echo -n "Disattivazione del servizio di stampa: "
        killall lpd
        echo
        ;;
  *)
        echo "Utilizzo: lpd {start|stop}"
        exit 1
esac

Dal momento che la stampa è controllata da un demone, quando si modifica il file di configurazione /etc/printcap, bisogna fare in modo che lpd lo rilegga. Questo lo si può ottenere arrestando e riavviando il servizio, oppure inviando al processo del demone un segnale di aggancio (SIGHUP):

kill -HUP pid_di_lpd

212.3.3   Stampante predefinita

Il file /etc/printcap permette di definire le code di stampa, comprese quelle che fanno riferimento a servizi remoti. Tra queste code, è necessario stabilire quale sia quella predefinita, ovvero quella che deve essere presa in considerazione quando non vi si fa riferimento in modo esplicito.

La coda predefinita (ovvero la stampante predefinita) corrisponde per tradizione al nome lp, ma questa definizione può essere alterata utilizzando la variabile di ambiente PRINTER. Se esiste, definisce il nome della stampante predefinita, altrimenti resta lp.

È importante tenere presente che la politica del proprio sistema di stampa potrebbe essere anche differente; per esempio, in mancanza di indicazioni la coda predefinita potrebbe essere quella corrispondente alla prima dichiarazione del genere nel file /etc/printcap. A questo proposito, è bene che la definizione della coda tradizionale lp, sia sempre la prima.

212.3.4   Clienti di stampa

Il cliente del sistema di stampa è un programma in grado di accodare una stampa. In generale, nei sistemi di stampa derivati da quello di BSD, si utilizza il programma lpr e in alcuni casi il programma lp:

lpr [opzioni] [file...]
lp [opzioni] [file...]

In condizioni normali, questi programmi sono in grado di mettere in stampa i file indicati alla fine della riga di comando, oppure, in loro mancanza, utilizzano per questo lo standard input. Sono molto poche le opzioni standard di questi programmi e, in generale, la cosa più importante è la definizione della coda di stampa a cui si vuole inviare il file:

lpr -P coda [file...]
lp -m coda [file...]

Lo schema sintattico semplificato mostra esattamente questa possibilità, sia per lpr che per lp. Si osservi in particolare che nel caso di lpr, la tradizione prevede anche che il nome della coda possa essere attaccato alla lettera dell'opzione.

Tabella 212.15. Alcune opzioni di lpr.

Opzione Descrizione
-Pcoda
-P coda
Permette di specificare una coda di stampa particolare, tra quelle previste all'interno di /etc/printcap. Se non viene utilizzata questa opzione, si fa riferimento alla stampante predefinita (che di solito è lp).
-m
Al termine della stampa, invia un messaggio attraverso mail all'utente che ha avviato il programma.
-#n_copie
Permette di specificare il numero di copie che si vuole siano stampate. Il numero di copie è indicato da un numero che segue il simbolo #.

Tabella 212.16. Alcune opzioni di lp.

Opzione Descrizione
-d coda
Permette di specificare una coda di stampa particolare, tra quelle previste all'interno di /etc/printcap. Se non viene utilizzata questa opzione, si fa riferimento alla stampante predefinita (che di solito è lp).
-m
Al termine della stampa, invia un messaggio attraverso mail all'utente che ha avviato il programma.
-n n_copie
Permette di specificare il numero di copie che si vuole siano stampate.

Segue la descrizione di alcuni esempi.

212.3.5   Esame delle code di stampa

Per conoscere la situazione delle code di stampa si utilizza il comando lpq:

lpq [opzioni] [numero_processo_di_stampa...] [utente...]

Il programma lpq esamina le code di stampa e restituisce lo stato di una o di tutte le stampe accodate dall'utente specificato. Se lpq viene eseguito senza alcun argomento, restituisce lo stato di tutte le stampe accodate.

Tabella 212.17. Alcune opzioni.

Opzione Descrizione
-P coda
Permette di specificare una coda particolare. Se non viene specificato, si fa riferimento a quella predefinita.
-l
Restituisce maggiori informazioni su ogni processo di stampa.

212.3.6   Rimozione dei processi di stampa dalle code

I processi di stampa che risultano ancora visibili nelle code, possono essere rimossi dall'utente che li ha generati, o dall'utente root.

lprm [opzioni] [utente...]

Permette di rimuovere uno o più processi di stampa accodati precedentemente. Il nome dell'utente può essere specificato solo se il comando viene utilizzato dall'utente root, nel senso che solo lui può interrompere la stampa di altri utenti. Se non viene specificato il nome dell'utente, si intende che si tratti dello stesso che ha eseguito lprm. Se non vengono specificati argomenti, l'esecuzione del comando lprm implica l'eliminazione della stampa in corso per l'utente che lo ha richiesto. Naturalmente, ciò vale solo se l'utente in questione ha, in quel momento, una stampa in esecuzione.

Se l'utente root utilizza lprm senza specificare un utente a cui fare riferimento, ottiene l'eliminazione di tutti i processi di stampa nelle code, attivi o meno che siano.

Tabella 212.18. Alcune opzioni.

Opzione Descrizione
-P coda
Permette di specificare una coda particolare. Se non viene specificata, si fa riferimento alla coda predefinita.
numero_processo_di_stampa...
Se tra gli argomenti vengono indicati uno o più numeri, questi si intendono riferiti ai processi di stampa che si vogliono eliminare.

212.3.7   Controllo del sistema di stampa

L'utente root controlla il sistema di stampa, ovvero il funzionamento dei vari demoni lpd, attraverso il programma lpc:

lpc [comando [argomento...]]

Le possibilità effettive di lpc dipendono dalle caratteristiche del sistema di stampa. In generale, per ogni coda di stampa configurata all'interno di /etc/printcap, lpc può eseguire le azioni seguenti:

Se lpc viene avviato senza argomenti, si attiva la modalità di comando evidenziata dalla presenza dell'invito lpc>. Se invece vengono forniti degli argomenti, il primo di questi viene interpretato come un comando, mentre i restanti come parametri del comando. È possibile inviare a lpc, attraverso lo standard input, un file contenente una serie di comandi.

Il programma lpc può essere eseguito anche da un utente comune, ma in tal caso sono disponibili solo alcune funzioni.

Tabella 212.19. Comandi a disposizione di tutti gli utenti.

Comando Descrizione
? [comando...]
help [comando...]
Visualizza una descrizione sintetica dei comandi elencati, oppure, se non ne viene indicato alcuno, l'elenco di tutti i comandi a disposizione.
exit
quit
Termina l'esecuzione di lpc.
status {all | coda}
Visualizza lo stato della coda di stampa locale indicata, oppure di tutte, se si utilizza la parola chiave all.

Tabella 212.20. Comandi a disposizione dell'utente root.

Comando Descrizione
abort {all | coda}
Termina l'esecuzione del demone attivo che si occupa della stampa nell'elaboratore locale, quindi disabilita la stampa, prevenendo l'avvio di altri demoni da parte di lpr. Quando viene riavviata la stampa, riprende il processo di stampa attivo nel momento dell'interruzione.
enable {all | coda}
disable {all | coda}
Abilita o disabilita l'uso della coda specificata, consentendo o impedendo la generazione di nuovi processi di stampa.
up {all | coda}
down {all | coda} messaggio
Abilita o disabilita l'uso della coda indicata, consentendo o bloccando la stampa dei processi di stampa esistenti.
start {all | coda}
stop {all | coda}
Avvia o arresta il demone che gestisce la coda. Nel caso di arresto, questo avviene al termine del processo di stampa eventualmente in esecuzione. Tuttavia, gli utenti possono continuare ad accodare stampe.
Il comando start può essere utile anche per riavviare un demone che per qualche ragione ha cessato di funzionare in modo inatteso.
topq coda \
  \[numero_processo_di_stampa...]
Cambia l'ordine di esecuzione dei processi di stampa ponendo quelli indicati in precedenza rispetto agli altri.

212.3.8   Particolarità del sistema BSD vero e proprio

Il sistema di stampa BSD prevede l'uso dei file /etc/hosts.equiv e /etc/hosts.lpd. Questi servono a elencare i nomi degli elaboratori remoti cui è consentito collegarsi per ottenere l'accesso al sistema di stampa locale. Per la precisione, è il file /etc/hosts.lpd che dovrebbe essere utilizzato per questo tipo di autorizzazione; tuttavia, dal momento che l'elenco contenuto in /etc/hosts.equiv serve già per consentire l'accesso attraverso programmi come Rsh (302.3), è ragionevole che anche a questi sia concesso di accedere al servizio di stampa.

È importante ribadire che con questo sistema di stampa, se non si predispone correttamente il file /etc/hosts.lpd, oppure il file /etc/hosts.equiv, o entrambi, non si ottiene l'accesso da clienti remoti.

Con il sistema di stampa BSD non è possibile accedere a stampanti remote se non è stata prevista una coda locale corrispondente nel file di configurazione /etc/printcap (con l'uso dei campi rm e rp). Per questo esistono anche dei programmi di servizio specifici che instaurano una connessione con il sistema remoto di stampa in modo autonomo. Si tratta di rlpr e rlpq, che vengono descritti più avanti.

212.3.9   Particolarità di LPRng

Il sistema di stampa LPRng (2) è molto più evoluto rispetto a quello della tradizione BSD, anche se di solito viene utilizzato in modo abbastanza conforme a quello; tuttavia consentirebbe di accedere a delle estensioni molto sofisticate, soprattutto per ciò che riguarda la stampa remota.

LPRng fa uso di /etc/printcap e di altri file di configurazione; precisamente si tratta di /etc/lprng/lpd.conf e di /etc/lprng/lpd.perms. Per quanto riguarda /etc/printcap, c'è da osservare che i record di definizione delle code, possono essere continuati su più righe, anche senza utilizzare il simbolo di continuazione (\).

Se il pacchetto utilizzato per installare LPRng è stato predisposto correttamente, non dovrebbe essere necessario indicare alcunché nel file di configurazione /etc/lprng/lpd.conf, che di solito viene fornito commentato completamente, con gli esempi delle varie direttive che vi potrebbero apparire. Eventualmente, può essere interessante abilitare la stampa di più copie attraverso la direttiva seguente nel file /etc/lprng/lpd.conf:

# Max number of copies.
mc#10000000

Il file /etc/lprng/lpd.perms serve a definire i permessi di accesso al servizio. Di solito, questo file viene fornito già predisposto per l'utilizzo locale normale; se si vuole concedere l'accesso da parte di clienti remoti è indispensabile modificare questo file, allo scopo di attivare i permessi necessari. Con ciò, si può intendere che LPRng non considera i file /etc/hosts.equiv e /etc/hosts.lpd.

# concede all'utente root sul servente di controllare i processi di stampa
ACCEPT SERVICE=C SERVER REMOTEUSER=root

# concede a chiunque di ottenere lo stato dei processi di stampa
ACCEPT SERVICE=S

# rifiuta le richieste di stampa dai nodi remoti
REJECT SERVICE=XRPQ NOT SERVER

# rifiuta tutto il resto
REJECT SERVICE=CSU

# concede agli utenti che accedono dai nodi originari,
# di eliminare i propri processi di stampa
ACCEPT SERVICE=M SAMEHOST SAMEUSER

# concede all'utente root sul servente di eliminare i processi di stampa
ACCEPT SERVICE=M SERVER REMOTEUSER=root
REJECT SERVICE=M

# tutte le altre operazioni sono concesse
DEFAULT ACCEPT

L'esempio appena mostrato rappresenta un file /etc/lprng/lpd.perms tipico, dove in particolare sono esclusi gli accessi da parte di clienti remoti. Per fare in modo di consentire l'accesso sommario da parte di una sottorete, si può modificare la direttiva seguente:

REJECT SERVICE=XRPQ NOT SERVER

Questa deve essere trasformata così:

REJECT SERVICE=XRPQ NOT SERVER NOT REMOTEIP=192.168.0.0/255.255.0.0

In tal modo, secondo l'esempio, si concede a tutta la sottorete 192.168.*.* di accedere.

Naturalmente, si può concedere l'accesso a chiunque, senza limitazioni, mettendo nel file /etc/lprng/lpd.perms soltanto la direttiva seguente:

DEFAULT ACCEPT

Un vantaggio importante nell'uso di LPRng sta nella possibilità di accedere direttamente a servizi di stampa remoti, senza dover passare per una coda locale configurata nel file /etc/printcap. Tutto è molto semplice: nelle situazioni in cui è consentito indicare il nome di una coda di stampa, si può usare la notazione seguente per accedere direttamente al servizio remoto corrispondente:

coda@nodo

L'esempio seguente invia alla stampa, presso la coda lp del nodo di rete roggen.brot.dg, il file lettera.

lpr -P lp@roggen.brot.dg lettera[Invio]

Infine, è bene tenere presente che è possibile verificare la correttezza della configurazione attraverso il programma di servizio checkpc (Check printcap):

checkpc [opzioni] [file_printcap]

Di solito si utilizza checkpc senza argomenti di alcun tipo, allo scopo di controllare il file /etc/printcap (ovvero quello predefinito), gli altri file di configurazione e le directory delle code. Il controllo riguarda sia la configurazione, sia i permessi dei file. È molto importante l'opzione -f, con la quale si richiede a checkpc di provvedere da solo a sistemare ciò che è possibile. Naturalmente, l'uso di checkpc con l'opzione -f è riservato all'utente root.

Prima di utilizzare checkpc è opportuno concludere il funzionamento di tutti i demoni lpd che fossero eventualmente in funzione.

checkpc -f[Invio]

A titolo di esempio viene mostrato quello che potrebbe essere generato da questo comando:

 Checking permission file '/etc/lpd.perms:/usr/etc/lpd.perms'
 Freeing Perms
 Done Perms
 LPD lockfile '/var/spool/lpd/lpd.lock.tizio.printer'
  Checking directory: '/var/spool/lpd'
   checking file '/var/spool/lpd/lpd.lock.tizio.printer'
 Truncating LPD log file '/var/spool/lpd/lpd.log.tizio'
 Checking /var/spool/lpd/lpd.log.tizio file '/var/spool/lpd/lpd.log.tizio'
checkpc: Warning - cannot open '/var/spool/lpd/lpd.log.tizio'
 lp: Checking printer 'lp'
 lp:  Checking directory: '/var/spool/lpd/lp'
 lp:   checking file '/var/spool/lpd/lp/control.lp'
 lp:   checking file '/var/spool/lpd/lp/status.lp'
 lp:   checking file '/var/spool/lpd/lp/status'
 lp:   checking file '/var/log/lp-errs'
 lp:   checking file '/var/log/lp-acct'
 lp: Checking log file '/var/log/lp-errs'
 lp:    'log' file 0 bytes long: no truncation
 lp: Checking accounting file '/var/log/lp-acct'
 lp:    'accounting' file 2316 bytes long: no truncation
 lp: Checking filter status file '/var/spool/lpd/lp/status'
 lp:    'filter status' file 0 bytes long: no truncation

212.4   Stampa remota attraverso Rlpr

Il pacchetto di programmi Rlpr, (3) estraneo al sistema di stampa BSD tradizionale, può essere molto utile per stampare utilizzando servizi remoti, senza passare per la configurazione del file /etc/printcap locale. Tuttavia, è il caso di ricordare che non c'è bisogno di tali programmi nel caso si disponga già di un sistema di stampa LPRng, in cui i programmi clienti normali sono in grado di fare questo da soli.

Rlpr sostituisce in pratica alcuni programmi di servizio, tipici del sistema di stampa BSD, con altri, caratterizzati da una lettera «r» iniziale, che sta per «remoto»:

rlpr [opzioni] [file_da_stampare...]
rlpq [opzioni] [numero_processo_di_stampa...] [utente...]
rlprm [opzioni] [utente...]

Come si può intuire, questi programmi sostituiscono, nell'ordine, lpr, lpq e lprm.

Questi programmi, per compiere il loro lavoro correttamente, richiedono i privilegi dell'utente root, pertanto hanno solitamente il bit SUID attivo, appartenendo all'utente root (SUID-root), come documentato chiaramente nelle pagine di manuale rlpr(1), rlpq(1) e rlprm(1).

Molte delle opzioni dei programmi originali, sono preservate; con qualche aggiunta e qualche modifica. In particolare:

Opzione Descrizione
-H nodo
--printhost=nodo
Definisce l'elaboratore remoto al quale ci si vuole rivolgere per ottenere la stampa. Al posto di utilizzare questa opzione si può sfruttare il nome della coda di stampa per includervi anche l'indicazione del nodo di rete remoto. Si osservi a tal fine la descrizione dell'opzione -P.
-Pcoda[@nodo]
--printer=coda[@nodo]
--queue=coda[@nodo]
Seleziona la coda di stampa remota. Se non si utilizza l'opzione -H, si può usare la notazione coda@nodo.

A titolo di esempio vengono mostrati due comandi equivalenti, per ottenere la stampa del contenuto della directory corrente, attraverso la coda lp presso l'indirizzo 192.168.1.1:

ls -l | rlpr --printhost=192.168.1.1 -Plp[Invio]

ls -l | rlpr -Plp@192.168.1.1[Invio]

212.4.1   Scelta automatica della stampante remota

Supponendo di avere a disposizione diverse stampanti remote, si potrebbe avere la necessità di selezionare in qualche modo la coda di stampa, cercando di sfruttare la prima stampante libera. Qui viene proposto un piccolo programma Perl che trova la stampante con la coda libera, oppure accoda in modo casuale, purché si tratti di una coda attiva. Per comodità, si può dare a questo programma proprio il nome lpr, in modo da renderlo trasparente all'utilizzatore.

#!/usr/bin/perl
#
# Indicare qui l'elenco delle code di stampa remote disponibili:
#
@printers = ("lp\@stampante1.brot.dg",
              "lp\@stampante2.brot.dg",
              "lp\@stampante3.brot.dg",
              "lp\@stampante4.brot.dg",
              "lp\@stampante5.brot.dg",
              "lp\@stampante6.brot.dg",
              "lp\@stampante7.brot.dg");
#
# Questa funzione esegue un comando del sistema operativo, restituendo
# quanto emesso dallo stesso attraverso i flussi standard.
#
sub system_output
{
    local ($command)  = $_[0];
    local ($line)     = "";
    local ($result)   = "";
    #
    # Esegue il comando.
    #
    open (COMMAND, "$command 2>&1 |");
    #
    # Recupera il risultato emesso dal comando.
    #
    while ($line = <COMMAND>)
      {
        $result = $result . $line
      }
    #
    # Chiude il flusso generato dal comando.
    #
    close (COMMAND);
    #
    return $result;
}
#
# Inizio del programma.
#
local ($arguments)      = "";
local ($noauto)         = 0;
local ($n)              = 0;
local ($test)           = "";
#
# Scandisce gli argomenti.
#
for ($n = 0; $n <= $#ARGV; $n++)
  {
    #
    # Analizza l'argomento $n-esimo.
    #
    if ($ARGV[$n] =~ m/^-P.*/
           || $ARGV[$n] =~ m/^--printer=.*/
           || $ARGV[$n] =~ m/^--queue=.*/)
      {
        #
        # In questo caso, è stata già specificata la coda di stampa
        # dall'utilizzatore.
        #
        $noauto    = 1;
      }
    #
    # Mette da parte l'argomento scandito.
    #
    $arguments = $arguments . " " . $ARGV[$n];
  }
#
# Se è stata specificata la stampante, non si procede in modo
# automatico.
#
if ($noauto)
  {
    system ("| rlpr $arguments");
    exit;
  }
#
# In condizioni normali, si cerca la prima stampante che risulta
# pronta.
#
for ($n = 0; $n <= $#printers; $n++)
  {
    $test = &system_output ("rlpq -P$printers[$n]");
    if ($test =~ m/^no entries$/)
      {
        system ("rlpr -P$printers[$n] $arguments");
        print STDOUT ("Stampa inviata a $printers[$n]\n");
        exit;
      }
  }
#
# Se non è stata trovata una stampante libera, si cerca una stampante
# che non abbia problemi.
#
while ($#printers > 0)
  {
    $n = (int ((rand) * $#printers) - 1);
    $test = &system_output ("rlpq -P$printers[$n]");
    if ($test !~ m/error/i
        && $test !~ m/warning/i)
      {
        system ("rlpr -P$printers[$n] $arguments");
        print STDOUT ("Stampa inviata a $printers[$n]\n");
        exit;
      }
    #
    # Elimina l'elemento dall'array.
    #
    splice (@printers, $n, 1);
  }
#
# Se nessuna stampante è nelle condizioni di poter stampare,
# avvisa.
#
print STDERR ("Nessuna delle stampanti previste è nelle condizioni ");
print STDERR ("di poter stampare.\n");

212.5   Stampa automatica da un file

Può capitare di utilizzare programmi che sono in grado esclusivamente di stampare utilizzando un file su disco. Per fare in modo che questo file venga trasmesso automaticamente alla stampante, si può realizzare uno script come quello seguente:

#!/bin/sh
PRINT_FILE=$1
PREVIOUS_SIZE="0"
while true
do
    sleep 2
    SIZE=`ls -s --block-size=1 $PRINT_FILE | sed "s/^ *\([0-9]*\) .*$/\1/"`
    if [ "$PREVIOUS_SIZE" = "$SIZE" ] && [ "$SIZE" != "0" ]
    then
        lpr $PRINT_FILE
        cat /dev/null > $PRINT_FILE
        PREVIOUS_SIZE="0"
    else
        PREVIOUS_SIZE="$SIZE"
    fi
done

In pratica, dopo un'attesa di due secondi, viene verificata la dimensione del file, confrontandola con la dimensione precedente (inizialmente è zero). Se la dimensione è cambiata, il file viene inviato alla stampa e viene annullato il suo contenuto.

Per interpretare cosa accade nel comando che serve a estrarre la dimensione del file, si può immaginare di averne uno di 1 Mibyte:

ls -s --block-size=1 mio_file.ps[Invio]

1048576 mio_file.ps

Il comando sed riceve questo risultato attraverso lo standard input ed estrae solo il valore numerico:

echo 1048576 mio_file.ps | sed "s/^ *\([0-9]*\) .*$/\1/"[Invio]

1048576

Questo meccanismo di stampa non può essere perfetto, però può essere una soluzione accettabile in mancanza di altro. Supponendo che lo script si chiami STAMPA, supponendo che il file da controllare sia /tmp/mio_file.ps, si potrebbe usare così:

STAMPA /tmp/mio_file.ps &[Invio]

212.6   Stampare attraverso X con un sistema di stampa BSD

Quando si inizia a utilizzare il sistema grafico X, provenendo dall'esperienza di un sistema operativo grafico estraneo alle convenzioni Unix, uno dei primi problemi (apparenti) che si incontrano è la stampa. Di solito, se ci si accontenta di stampare senza pretendere di interagire con la stampante, l'operazione è abbastanza semplice, perché si può usare un comando per la stampa come se si trattasse di programmi normalissimi senza grafica. In effetti, la standardizzazione del formato PostScript è molto importante. Praticamente tutti i programmi che devono emettere qualcosa di diverso dal semplice testo ASCII, utilizzano il formato PostScript. Restano allora solo un paio di problemi:

Generalmente, i programmi che hanno la necessità di stampare propongono una riga di comando per la stampa, per cui è anche possibile utilizzare un sistema di stampa che dispone di un cliente diverso dal solito programma lpr.

Alcuni programmi più vecchi richiedono solo l'indicazione della voce del file /etc/printcap e quindi pretendono di utilizzare il programma lpr con l'opzione -P.

Figura 212.32. Questo è un esempio di un programma che è in grado di stampare solo attraverso lpr. Se non viene indicato il nome di una coda di stampa, si fa riferimento a lp, o comunque a quella predefinita.

stampa-x-ghostview

Figura 212.33. Questo è un esempio di un programma normale che permette l'indicazione di una riga di comando completa (o quasi). Non deve essere inserito il nome del file da stampare che di norma viene fornito attraverso lo standard input.

stampa-x-starwriter

212.7   Sviluppo attuale

Il sistema di stampa tradizionale dei sistemi Unix, descritto in questo capitolo, consente soltanto di inviare un file alla stampante. Sta all'amministratore del sistema configurare le code di stampa in modo da predisporre dei filtri appropriati.

Così facendo, però, diventa difficile richiedere alla stampante delle opzioni di funzionamento particolari; per esempio non si può selezionare il formato della carta (supponendo di disporre di cassetti con formati alternativi), così come non è possibile abilitare o disabilitare la stampa fronte-retro (duplex) automatica, a meno di agire fisicamente sulla stampante.

Per risolvere questo problema, esiste la possibilità di definire dei file di configurazione particolari, associati ognuno a un tipo specifico di stampante: i file PPD (PostScript printer description). Benché il nome suggerisca la relazione stretta con stampanti PostScript, in pratica si possono realizzare file PPD anche per altri tipi.

Per approfondire l'argomento si può leggere il documento Tutorial on CUPS and Foomatic, in particolare la parte terza: Some theoretical background: CUPS, PPDs, PostScript and GhostScript, di Till Kamppeter e Kurt Pfeifle <http://www.linuxprinting.org/kpfeifle/LinuxKongress2002/Tutorial/III.PostScript-and-PPDs/III.PostScript-and-PPDs.html>. Il sistema di stampa Cups viene introdotto nel capitolo 219, ma senza approfondire il problema dei file PPD.

212.8   Riferimenti


1) BSD line printing spool system   UCB BSD

2) LPRng   GNU GPL o Artistic

3) Rlpr   GNU GPL


Appunti di informatica libera 2008 --- Copyright © 2000-2008 Daniele Giacomini -- <appunti2 (ad) gmail·com>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome stampa.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home]

Valid ISO-HTML!

CSS validator!

Gjlg Metamotore e Web Directory