[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]

63. 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 una pipeline. I filtri di stampa vengono quindi utilizzati sia per adattare i file da stampare alle particolari caratteristiche della stampante che si ha a disposizione, sia per ottenere effetti particolari, come l'aggiunta di intestazioni. *1*

Il sistema di stampa utilizzato normalmente nelle distribuzioni GNU/Linux, è quello derivato dallo Unix BSD (Berkeley Software Distribution): lpr.

Questa parte del documento, dedicata alla stampa, fa riferimento a concetti che verranno chiariti solo più avanti, come la stampa remota e l'utilizzo di strumenti grafici. Sotto questo aspetto, l'argomento dovrebbe essere trattato più tardi, ma di sicuro l'esigenza di stampare si avverte molto presto, e per questo viene anticipato questo argomento.

63.1 Kernel

Per poter utilizzare la stampante, occorre avere compilato il kernel inserendo la gestione della porta parallela e della stampa. Se si utilizza un elaboratore con architettura i386, occorre specificarlo con l'opzione apposita.

Con i nuovi kernel non dovrebbero porsi problemi per la gestione simultanea di attività diverse attraverso la porta parallela.

63.2 Dispositivi di stampa

I dispositivi di stampa sono le porte parallele, o seriali, utilizzate per la connessione con le stampanti. In origine, il nome assegnato alle porte parallele destinate alla stampa, dipendeva dell'indirizzo I/O di queste, secondo l'elenco seguente:

Di solito, la prima porta parallela utilizza l'indirizzo di I/O 0x378 e di conseguenza, quasi sempre, il dispositivo utilizzato per la stampa è stato /dev/lp1. Ma questo ragionamento non vale più per i kernel più recenti che gestiscono il Plug & Play dove di solito, la prima porta stampante corrisponde a /dev/lp0.

Per controllare è sufficiente eseguire dmesg | less e cercare una riga simile a quella seguente:

lp1 at 0x0378, (polling)

63.2.1 Stampa brutale

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

cp stampa.prn /dev/lp1

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

C:> COPY /B STAMPA.PRN LPT1

63.3 Sistema di stampa BSD

Il sistema di stampa BSD prevede la gestione di una coda e di un sistema di accoglimento o rifiuto di richieste di stampa da elaboratori remoti.

63.3.1 Coda di stampa

La coda di stampa è gestita schematicamente attraverso i componenti seguenti:


Figura 63.1: Schema semplificato della gestione della coda di stampa.

Le stampe che si accodano all'interno di una directory ricevono un numero che serve per distinguere il processo di stampa relativo. Le stampe accodate sono quindi dei processi di stampa accodati.

Il demone lpd non fa tutto da solo: la prima copia di questo programma si occupa di dirigere i lavori e demanda tutte le operazioni ad altre copie di se stesso.

63.3.2 Server di stampa

La prima copia del demone lpd si occupa anche di stare in ascolto della porta printer (515/TCP) in modo da poter ricevere richieste di stampa da altri elaboratori collegati in rete. L'utilizzo del servizio non è concesso a tutti indiscriminatamente, è necessario che il nome, o l'indirizzo IP dell'elaboratore che ne fa richiesta, sia presente nel file /etc/hosts.equiv ( 87.1.1), oppure /etc/hosts.lpd.

Il file /etc/hosts.equiv è quello che viene utilizzato per consentire l'uso di programmi come rsh e rcp, e sotto questo aspetto è ragionevole pensare che si consenta automaticamente anche l'uso della stampante. Il file /etc/hosts.lpd è invece specifico per la gestione della stampa.


Figura 63.2: Lo stesso demone lpd è il responsabile dell'inserimento in coda dei file da stampare, provenienti da elaboratori remoti.

Il demone lpd, dal momento che non offre esclusivamente servizi di rete, non viene messo sotto il controllo di inetd. Di norma viene avviato direttamente dalla procedura di inizializzazione del sistema.

63.3.3 # lpd

lpd [<opzioni>]

È il demone che si occupa di gestire la coda di stampa. Normalmente viene avviato la prima volta tramite la procedura di inizializzazione del sistema. In particolare, appena avviato, riprende l'esecuzione delle stampe rimaste in sospeso nelle code.

Opzioni

-l

Permette di avere una registrazione (log) delle richieste di stampa ricevute attraverso la rete. Questa opzione viene utilizzata normalmente a scopo diagnostico.

<numero-porta>

L'indicazione di un numero tra gli argomenti, permette di definire esplicitamente il numero di porta su cui si vuole che lpd resti in ascolto per eventuali richieste di stampa remote.

File

63.3.4 /etc/hosts.lpd

Questo file serve per elencare i nomi degli elaboratori cui è consentito collegarsi e utilizzare le stampanti dell'elaboratore locale.

Anche gli elaboratori elencati nel file /etc/hosts.equiv sono ammessi a utilizzare le stampanti locali. Ma questo file riguarda piuttosto il concetto generale dell'equivalenza, e viene utilizzato soprattutto per consentire l'accesso a programmi come rsh ( 87.3.2).

In generale quindi, se quello che si vuole è solo concedere l'utilizzo della stampante, è opportuno inserire i nomi di quegli elaboratori in questo file e non in /etc/hosts.equiv.

L'esempio seguente mostra il contenuto del file /etc/hosts.lpd quando si vuole concedere a roggen.brot.dg di utilizzare la stampante locale.

roggen.brot.dg

63.3.5 Stampante predefinita

Come accennato, il file /etc/printcap permette di definire le caratteristiche delle stampanti utilizzabili dal sistema, comprese quelle remote. Tra queste, è necessario stabilire la stampante predefinita, ovvero quella che deve essere presa in considerazione quando non si fa un riferimento preciso a una stampante particolare.

La stampante predefinita è normalmente quella corrispondente 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.

63.3.6 $ lpr

lpr [<opzioni>] [<file>...]

Si occupa di accodare la stampa dei file indicati come argomento oppure di quanto acquisito dello standard input.

Alcune opzioni

-P<stampante> | -P <stampante>

Permette di specificare una stampante particolare, tra quelle previste all'interno di /etc/printcap. Se non viene specificato, si fa riferimento alla stampante predefinita (che di solito è lp).

-h

Sopprime l'emissione della pagina di separazione.

-m

Invia un messaggio attraverso mail al termine della stampa.

-r

Al termine della stampa o dell'invio alla coda, elimina il file. Funziona in combinazione con il parametro -s.

-s

Invece di copiare il file da stampare nella directory che funge da coda di stampa, si limita a creare un collegamento simbolico. Se si utilizza questa opzione, il file originale non può essere rimosso o modificato fino a che la stampa non è terminata.

-#<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 #.

-i [<num-colonne>]

Permette di definire un rientro globale del testo da stampare del numero di colonne (caratteri) specificato. Se questo valore non viene fornito, il rientro predefinito è di 8 caratteri.

Esempi

lpr lettera

Accoda la stampa del file lettera utilizzando la stampante predefinita.

lpr -P laser lettera

Accoda la stampa del file lettera utilizzando la stampante identificata con il nome laser all'interno del file /etc/printcap.

lpr -Plaser lettera

Esattamente come nell'esempio precedente.

ls -l | lpr

Accoda la stampa dell'elenco della directory corrente. In pratica, viene accodato quanto proveniente dallo standard input del comando ls -l.

63.3.7 $ lpq

lpq [<opzioni>] [<numero-processo-di-stampa>...] [<utente>...]

lpq esamina la coda 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.

Alcune opzioni

-P <stampante>

Permette di specificare una stampante particolare. Se non viene specificato, si fa riferimento alla stampante predefinita.

-l

Restituisce maggiori informazioni su ogni processo di stampa.

63.3.8 $ lprm

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.

Alcune opzioni

-P <stampante>

Permette di specificare una stampante particolare. Se non viene specificato, si fa riferimento alla stampante predefinita.

-

Se viene indicato un solo trattino (-) come argomento, lprm eliminerà tutti i processi di stampa appartenenti all'utente che ha eseguito il comando. Se è l'utente root a eseguire lprm in questo modo, vengono eliminate tutte le stampe in coda.

<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.

63.3.9 # lpc

lpc [<comando> [<argomento>...]]

Permette di controllare le operazioni del sistema di stampa. Per ogni stampante configurata all'interno di /etc/printcap può eseguire le azioni seguenti:

Se lpc viene avviato senza argomenti, si attiva la modalità di comando evidenziata dalla presenza dell'invito (prompt) 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.

lpc può essere eseguito anche da un utente comune, ma in tal caso potranno essere eseguite solo alcune funzioni.

Comandi a disposizione di tutti gli utenti

? [<comando>...] | help [<comando>...]

Visualizza una breve descrizione dei comandi eventualmente elencati, oppure l'elenco dei comandi a disposizione.

exit | quit

Termina l'esecuzione di lpc.

restart { all | <stampante>}

Tenta di riavviare il demone di stampa. Ciò può essere utile quando per qualche motivo inspiegabile il demone ha interrotto la sua attività lasciando dei processi di stampa nella coda.

status { all | <stampante>}

Visualizza lo stato della stampante locale indicata.

Comandi a disposizione dell'utente root

abort { all | <stampante>}

Termina l'esecuzione del demone attivo che si occupa della stampa nell'elaboratore locale e quindi disabilita la stampa, prevenendo l'avvio di altri demoni da parte di lpr. Quando verrà riavviata la stampa, verrà ripreso il processo di stampa che era attivo nel momento dell'interruzione.

clean { all | <stampante>}

Elimina i file temporanei, i file di dati e di controllo che non possono essere stampati, cioè quelli che non fanno parte di un processo di stampa completo.

disable { all | <stampante>}

Disabilita l'uso della stampante specificata impedendo la generazione di nuovi processi di stampa.

down { all | <stampante>} <messaggio>

Disabilita l'uso della stampante indicata e fornisce un messaggio di spiegazione.

enable { all | <stampante>}

Abilita l'uso della stampante specificata.

start { all | <stampante>}

Abilita la stampa e avvia i demoni necessari.

stop { all | <stampante>}

Interrompe il demone che gestisce la coda al termine del processo di stampa eventualmente in esecuzione e disabilita la stampa. Gli utenti possono continuare ad accodare stampe che però, per il momento, non vengono gestite.

topq <stampante> [<numero-processo-di-stampa>...] [<utente>...]

Cambia l'ordine di esecuzione dei processi di stampa ponendo quelli indicati in precedenza rispetto agli altri. Se viene indicato il nome di uno o più utenti, i processi di stampa accodati da questi otterranno la precedenza.

up { all | <stampante>}

Abilita la stampa e avvia un nuovo demone di stampa se necessario, annullando l'effetto di un precedente comando down.

63.3.10 /etc/printcap

Il file /etc/printcap è il punto più delicato del sistema di stampa BSD. Dalla sua corretta configurazione dipende il funzionamento delle stampe. Il suo contenuto è organizzato in record, dove ognuno di questi contiene le informazioni relative a una stampante. I campi di questi record sono separati da due punti verticali (:) e possono essere spezzati su più righe utilizzando la barra obliqua inversa (\) seguita immediatamente dal codice di interruzione di riga.

All'interno di questo file si possono trovare le indicazioni di diverse stampanti che possono fare capo a un'unica stampante reale, quando di utilizzano diverse possibili configurazioni per la stessa. Il simbolo # rappresenta l'inizio di un commento e non viene interpretato da lpd. Segue un esempio di questo file.

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

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

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

# 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/filter:

Il primo campo di ogni record identifica tutti i possibili pseudonimi di una certa stampante. Questi sono separati da una barra verticale. Gli altri campi contengono tutti una sigla identificativa composta da due caratteri e un valore eventuale.

La compilazione di questo file è molto delicata: in particolare, occorre fare bene attenzione a non lasciare spazi di qualunque tipo dopo i simboli di continuazione (\).

Quando si modifica il file /etc/printcap, occorre ricordare di inviare un segnale SIGHUP al demone lpd, oppure lo si deve riavviare, altrimenti le modifiche non avranno effetto.

kill -HUP <pid-di-lpd>

Vedere printcap(5).

63.3.10.1 Campi

I campi possono essere di diverso tipo e a seconda di questo cambia il modo con cui i dati relativi sono indicati.

I campi che possono essere utilizzati in un record del file /etc/printcap sono molti. Quello che segue è un elenco parziale di quelli più usati.

---------

if

Input Filter. Il nome di un filtro di input, cioè di un programma che si occupa di filtrare i dati in ingresso.

lf

Log File. Il nome di un file all'interno del quale verranno registrati gli errori di una stampante.

lp

Line Printer. Il nome del dispositivo di stampa.

mx

MaX. Il valore numerico della dimensione massima (in multipli di 1024 byte) di un file di stampa. Di solito, questo campo viene indicato con il valore 0 per non porre alcun limite di dimensione.

rm

Remote Machine. Il nome di un elaboratore remoto da utilizzare per la stampa.

rp

Remote Printer. Il nome di una stampante remota, cioè il nome utilizzato nell'elaboratore remoto indicato nel campo rm.

sd

Spool Directory. Il nome della directory usata come coda della stampante.

sf

Suppress Feed. È un campo booleano che, se presente, elimina l'avanzamento della carta alla fine di ogni processo di stampa.

sh

Suppress Header. È un campo booleano che, se presente, elimina l'emissione di una pagina di intestazione (ovvero di separazione) tra un processo di stampa e il successivo.

---------

Nell'elenco precedente si fa volutamente riferimento a un unico tipo di filtro, if. In generale non dovrebbe essere necessario l'uso di altri campi riferiti a filtri.

63.3.10.2 Filtri

Più avanti, in questo capitolo, vengono descritti alcuni tipi di filtri di stampa. Il filtro di stampa non è altro che un programma, o uno script, che trasforma in qualche modo i dati ricevuti dallo standard input, restituendo il risultato attraverso lo standard output.

63.3.10.3 Esempi

Dopo la descrizione dei vari campi che possono comporre un record del file /etc/printcap, conviene rivedere e descrivere alcuni degli esempi visti all'inizio.

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

In questo caso, 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/lp1:\
	:if=/var/spool/lpd/lp/filter:

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 if. Il file /var/spool/lpd/lp/filter potrebbe essere sia un programma che 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/filter:

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 stampante remota.

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 stampante corrispondente al nome lp dell'elaboratore remoto non ha un filtro.

63.3.11 /var/spool/lpd/*/

Le directory per le code di stampa sono definite attraverso il campo sd dei record contenuti in /etc/printcap. Normalmente, nelle distribuzioni GNU/Linux si utilizzano directory discendenti da /var/spool/lpd/, secondo la convenzione per cui il nome della directory corrisponde al nome della stampante. In pratica si ha quasi sempre una struttura di questo tipo: /var/spool/lpd/<stampante>/.

Ognuna di queste directory è il contenitore dei processi di stampa di una particolare stampante, in attesa, o in corso di stampa. Al loro interno, durante l'uso del sistema di stampa, si trovano in particolare i file seguenti.

Alle volte si ha difficoltà a eliminare una coda di stampa, cioè a eliminare una stampa. In questi casi, l'amministratore del sistema può eliminare semplicemente i file accumulati in coda, cioè cf* e df*.

Se si teme che lo spazio su disco venga esaurito dall'accumulo di code di stampa, si può inserire il file minfree nelle directory relative che si vogliono controllare. Questo file deve contenere un numero corrispondente alla quantità di blocchi che si vuole restino comunque liberi.

63.4 File per la stampa

Negli ambienti Unix si utilizzano normalmente due tipi fondamentali di file per la stampa:

Teoricamente, i file di testo sono stampabili con qualunque tipo di stampante, mentre i file PostScript richiedono una stampante PostScript. In pratica, quasi sempre non è possibile stampare un file di testo così com'è, e raramente si dispone di una stampante PostScript.

63.4.1 File di testo

Negli ambienti Unix i file di testo (o file ASCII) seguono la convenzione dell'interruzione di riga attraverso il codice ASCII <LF>.

Con il sistema operativo Dos è stato introdotto un codice differente, corrispondente a <CR><LF>. La maggior parte delle stampanti in circolazione è adatta a quest'ultimo tipo di interruzione di riga, per cui, il solo carattere <LF> produce un avanzamento alla riga successiva, senza il ritorno alla prima colonna.

Quando si invia un file di testo in stile Unix a una stampante che richiede l'interruzione di riga in stile Dos, si ottiene il noto effetto scalettatura.

Per esempio, supponendo di voler stampare il file seguente,

Uno
Due
Tre

Si ottiene quello che segue.

Uno
   Due
      Tre

Per ovviare a tale inconveniente, prima di inviare un file di testo Unix a una stampante normale, occorre trasformare i codici di interruzione di riga in modo che comprendano sia <CR> che <LF>.

Il tipico programma in grado di eseguire questa conversione è unix2dos. Di questo ne esistono diverse edizioni, tutte incompatibili tra loro, accomunate solo dallo scopo. Qui si fa riferimento a un programma filtro, ovvero a uno unix2dos che riceve il file da convertire dallo standard input e che restituisce il risultato attraverso lo standard output. I filtri di stampa sono descritti più avanti in questo capitolo, per il momento dovrebbe bastare sapere che si può utilizzare il programma unix2dos prima di inviare il file al programma lpr, come nell'esempio seguente:

cat esempio.txt | unix2dos | lpr

Come accennato, il programma unix2dos non è standard e a volte si può incontrare una versione che non funziona esattamente come negli esempi indicati qui. Eventualmente conviene consultare la sua documentazione: unix2dos(1).

In alternativa al programma unix2dos, si può scrivere uno script Perl molto semplice e intuitivo, anche per chi non conosce tale linguaggio (capitolo 137).

#!/usr/bin/perl
#======================================================================
# filtro-crlf.pl < <file-input> > <file-output>
#======================================================================

$riga = "";

while( $riga = <STDIN> ) {

    #------------------------------------------------------------------
    # Elimina il carattere <LF> finale.
    #------------------------------------------------------------------
    chop $riga;

    #------------------------------------------------------------------
    # Emette la riga con l'aggiunta di <CR> e <LF>.
    #------------------------------------------------------------------
    print "$riga\r\n";
};
#======================================================================

63.4.2 File PostScript

Il sistema PostScript ha introdotto una sorta di rivoluzione nel modo di stampare: attraverso un linguaggio standardizzato rendeva la stampa indipendente dal tipo particolare di stampante utilizzato. L'unico inconveniente delle stampanti PostScript era, ed è, il prezzo.

Fortunatamente, negli ambienti Unix è disponibile il programma Ghostscript in grado di trasformare un file PostScript in diversi formati, ognuno compatibile con un diverso tipo di stampante.

Nella maggior parte dei casi, quando cioè non si dispone di una stampante PostScript, si devono convertire i file PostScript in un formato accettabile dalla propria stampante. L'uso dei filtri di stampa permette di automatizzare questa operazione. Nel prossimo capitolo viene descritto in che modo questi file PostScript possono essere gestiti.

63.5 Filtri di stampa

Attraverso il file /etc/printcap, per ogni singolo record di descrizione di una stampante è possibile definire un gran numero di filtri di stampa, ognuno con uno scopo particolare. Di fatto, è preferibile limitarsi a utilizzarne uno solo, e precisamente quello del campo if, o Input Filter.

63.5.1 if

Il programma o lo script indicato nel campo if riceve alcuni argomenti. Secondo quanto si trova documentato in printcap(5), la sintassi con cui viene avviato il filtro è la seguente:

<filtro-if> [-c] -w<larghezza> -l<lunghezza> -i<rientro> -n <utente> -h <host> <file-di-accounting>

In particolare:

A meno di non studiare in modo approfondito l'uso del sistema di stampa BSD, la maggior parte di questi argomenti sono inutilizzabili. È molto più facile costruire un file di configurazione aggiuntivo, da fare leggere al filtro ogni volta che viene avviato, piuttosto che pretendere di fare tutto attraverso l'interpretazione degli argomenti ottenuti automaticamente.

In ogni caso, si può contare su due argomenti, eventualmente utilizzabili per produrre intestazioni, o per produrre un registro (un log): il nome dell'utente e il nome dell'elaboratore.

63.5.2 Filtro diagnostico

Gli argomenti forniti al filtro di stampa potrebbero essere diversi da quanto dichiarato dalla documentazione e quindi vale la pena di costruire la prima volta un filtro diagnostico simile allo script seguente:

#!/bin/bash
pwd > /tmp/test-stampa
echo $1 >> /tmp/test-stampa
echo $2 >> /tmp/test-stampa
echo $3 >> /tmp/test-stampa
echo $4 >> /tmp/test-stampa
echo $5 >> /tmp/test-stampa
echo $6 >> /tmp/test-stampa
echo $7 >> /tmp/test-stampa
echo $8 >> /tmp/test-stampa
echo $9 >> /tmp/test-stampa
echo ${10} >> /tmp/test-stampa
echo ${11} >> /tmp/test-stampa

Come si può vedere, viene creato il file /tmp/test-stampa con l'indicazione della directory corrente (pwd) e quindi l'elenco dei contenuti dei vari parametri, ovvero l'elenco degli argomenti ricevuti.

La voce (il record) di /etc/printcap che utilizza questo filtro potrebbe essere composta nel modo seguente (/var/spool/lpd/prova/filtro-prova è il nome dello script visto sopra).

prova:\
	:sd=/var/spool/lpd/prova:\
	:mx#0:\
	:sh:\
	:lp=/dev/lp1:\
	:if=/var/spool/lpd/prova/filtro-prova:

Quando si stampa utilizzando la voce prova non si ottiene alcuna stampa: viene creato il file /tmp/test-stampa. *2*

daniele@dinkel.brot.dg$ lpr -Pprova lettera

Il comando precedente, dovrebbe generare il file /tmp/test-stampa con il contenuto seguente:

/var/spool/lpd/prova
-w132
-l66
-i0
daniele
-h
dinkel.brot.dg

Si può subito notare che l'opzione -n non esiste: viene fornito il nome dell'utente senza il prefisso di alcuna opzione. Un'altra cosa molto importante è la directory corrente: corrisponde sempre alla directory della coda di stampa.

63.5.3 Filtri elementari

Quando si realizza un filtro di stampa personalizzato, raramente si vanno a cercare sottigliezze che sono comunque già disponibili all'interno di pacchetti di filtri già fatti da altri. Di solito ci si accontenta di trasformare lo standard input e di restituire uno standard output adatto alle proprie esigenze, ignorando completamente gli argomenti che il filtro riceve.

L'esempio tipico è il filtro che permette di stampare un file di testo in stile Unix su una stampante che richiede la conclusione della riga attraverso <CR><LF>. Come già accennato all'inizio del capitolo, basta utilizzare il programma unix2dos.

Bisogna fare attenzione: il filtro di stampa riceve degli argomenti, anche se questi non servono. Se si tenta di utilizzare unix2dos direttamente come filtro, si rischia di ottiene solo una segnalazione di errore: unix2dos potrebbe non essere in grado di comprendere gli argomenti ricevuti. Per risolvere il problema, occorre realizzare uno script, in modo da poter eliminare gli argomenti inutilizzati.

Segue l'esempio di una voce del file /etc/printcap.

testo:\
	:sd=/var/spool/lpd/testo:\
	:mx#0:\
	:sh:\
	:lp=/dev/lp1:\
	:if=/var/spool/lpd/testo/filtro:

Segue l'esempio dello script utilizzato come filtro.

#!/bin/bash
/usr/bin/unix2dos

È importante osservare un paio di particolari:

63.5.4 Filtri PostScript

Tutti i filtri di stampa in grado di convertire file PostScript in qualcosa di stampabile senza una stampante PostScript, si avvalgono del programma Ghostscript (gs). L'esempio seguente mostra uno script che riceve dallo standard input un file PostScript e restituisce attraverso lo standard output un file stampabile con una HP Laserjet o compatibile.

#!/bin/bash
/usr/bin/gs -q -dNOPAUSE -sPAPERSIZE=a4 -sDEVICE=laserjet -sOutputFile=- -

63.5.5 Problemi

In passato è capitato che una particolare versione del sistema di stampa BSD per GNU/Linux avesse un difetto che non le permetteva di utilizzare il flusso di dati proveniente dal filtro di stampa.

Nel caso dovesse verificarsi nuovamente questa situazione, si può utilizzare un trucco: il filtro di stampa riceve i dati dallo standard input nel modo solito e li trasforma. Quindi, invece di emettere il risultato della sua elaborazione attraverso lo standard output, lo invia a un'altra coda di stampa.

In pratica, si può supporre che il file /etc/printcap sia composto come segue:

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

testo:\
	:sd=/var/spool/lpd/testo:\
	:mx#0:\
	:sh:\
	:lp=/dev/lp1:\
	:if=/var/spool/lpd/testo/filtro:

Il filtro /var/spool/lpd/testo/filtro potrebbe essere realizzato nel modo seguente:

#!/bin/bash
/usr/bin/unix2dos | lpr -Plp

63.5.6 Filtri sofisticati

Non è necessario complicarsi troppo la vita. Spesso la distribuzione GNU/Linux che si ha a disposizione è già predisposta in modo da facilitare la creazione di filtri di stampa. In particolare, Red Hat fornisce un pannello di controllo grafico intuitivo.

Anche quando non si è così fortunati, esiste sempre un'alternativa migliore allo scriversi il proprio filtro (salvo casi particolari). Un esempio è ApsFilter che senza molta fatica genera da solo il file /etc/printcap, le directory per le code di stampa e i filtri necessari.

Infine, è il caso di ricordare il pacchetto PSUtils che contiene programmi in grado di rielaborare file PostScript, cosa utile per esempio quando su un solo foglio si vogliono stampare più pagine ridotte.

63.6 Accessori di stampa

Alcuni programmi estranei al pacchetto normale del sistema di stampa BSD possono essere molto utili e vale la pena di conoscerli.

63.6.1 # lptest

lptest [<larghezza>] [<altezza>]

Emette attraverso lo standard output una serie di caratteri, e in questo modo è utilizzabile per una prova di stampa. Il primo argomento permette di definire la larghezza della riga da emettere: il valore predefinito è 79. Il secondo argomento permette di definire la quantità di righe da emettere: il valore predefinito è 200. Si tratta di una prova di stampa utile solo per le stampanti a impatto come quelle ad aghi, a catena, a margherita...

63.6.2 # rlpr

rlpr [<opzioni>] [<file-da-stampare>...]

rlpr è inteso come un sostituto di lpr per facilitare la stampa attraverso un servizio remoto. Per raggiungere questo risultato, rlpr contatta direttamente il servizio di stampa presso l'elaboratore remoto, dove presumibilmente dovrebbe esserci il demone lpd in ascolto. A parte la necessità di predisporre opportunamente il servizio remoto, nel senso che lì deve essere stato configurato il file /etc/hosts.lpd in modo da consentire l'accesso per la stampa, all'interno del client non è più necessario predisporre un record nel file /etc/printcap.

Per compiere il suo lavoro, rlpr deve contattare il servizio remoto utilizzando una porta privilegiata, e per arrivare a questo deve essere avviato a sua volta con i privilegi dell'utente root. Per questo, rlpr viene installato normalmente appartenente all'utente root con il bit SUID attivo (in breve, SUID-root). rlpr potrebbe funzionare anche diversamente, attraverso un servizio proxy offerto da rlprd; eventualmente si può consultare per questo la documentazione originale: rlpr(1).

Alcune opzioni

rlpr è compatibile con la maggior parte delle opzioni riconosciute da lpr. Qui vengono annotate solo alcune opzioni particolari.

-H <host> | --printhost=<host>

Questa opzione 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 stampante per includervi anche l'indicazione del nodo remoto. Si osservi per questo la descrizione dell'opzione -P.

-P <stampante>[@<host>] | --printer=<stampante>[@<host>]

Seleziona la stampante remota. Se non si utilizza l'opzione -H, si può usare la notazione <stampante>@<host>.

Esempi

ls -l | rlpr --printhost=192.168.1.1 --printer=lp

Invia per la stampa il risultato dell'esecuzione del comando ls -l utilizzando la stampante lp dell'elaboratore identificato dal numero IP 192.168.1.1.

ls -l | rlpr --printer=lp@192.168.1.1

Esattamente come nell'esempio precedente, con la differenza che l'indirizzo dell'elaboratore remoto è stato incorporato nella definizione della stampante.

rlpr --printer=lp@dinkel.brot.dg lettera.ps

Invia per la stampa il file lettera.ps utilizzando la stampante lp dell'elaboratore identificato dal nome dinkel.brot.dg.

63.6.3 # rlpq

rlpq [<opzioni>] [<numero-processo-di-stampa>...] [<utente>...]

rlpq esamina la coda di stampa di un elaboratore remoto, senza che ci sia la necessità di avere predisposto al riguardo il file /etc/printcap. rlpq è progettato per essere compatibile con il programma lpq normale, e fa parte dello stesso pacchetto di rlpr.

Alcune opzioni

rlpq è compatibile con la maggior parte delle opzioni riconosciute da lpq. Qui vengono annotate solo alcune opzioni particolari.

-H <host> | --printhost=<host>

Questa opzione definisce l'elaboratore remoto. Al posto di utilizzare questa opzione si può sfruttare il nome della stampante per includervi anche l'indicazione del nodo remoto. Si osservi per questo la descrizione dell'opzione -P.

-P <stampante>[@<host>] | --printer=<stampante>[@<host>]

Seleziona la stampante remota la cui coda si vuole interrogare. Se non si utilizza l'opzione -H, si può usare la notazione <stampante>@<host>.

63.7 Stampare attraverso X

Quando si inizia a utilizzare il sistema grafico X, provenendo dall'esperienza MS-Windows, uno dei primi problemi (apparenti) che si incontrano è la stampa: in che modo i programmi accodano le stampe? Semplice: utilizzano un comando per la stampa come se fossero normalissimi programmi 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 diverso dal programma lpr.

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


Figura 63.3: Questo è un esempio di un programma che è in grado di stampare solo attraverso lpr. Se non viene indicato alcun nome di stampante, si fa riferimento a lp, o comunque alla stampante predefinita.


Figura 63.4: 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.

---------------------------

Appunti Linux 1999.09.21 --- Copyright © 1997-1999 Daniele Giacomini --  daniele @ pluto.linux.it


1.) Recentemente sono state introdotte nel mercato stampanti che non si accontentano più di ricevere un file per iniziare a stampare, ma richiedono l'utilizzo di un protocollo di comunicazione. Queste stampanti, per funzionare, hanno bisogno della presenza di un programma speciale, predisposto dalla casa produttrice, e non sono compatibili in alcun modo con GNU/Linux. 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 GNU/Linux.

2.) Se si fanno modifiche al file /etc/printcap bisogna ricordare di inviare un segnale di aggancio al demone lpd per fare in modo che venga riletto questo file: kill -s SIGHUP <pid-di-lpd>.


[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]