Capitolo successivo Capitolo precedente Indice

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

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

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

64.1 Kernel

Per poter utilizzare la stampante, occorre avere compilato il kernel inserendo la gestione della stampa. All'interno del gruppo Character devices occorre rispondere affermativamente alla domanda seguente se si utilizza la porta parallela.

Nel caso in cui si debba condividere la porta parallela per la stampa e per una connessione PLIP con un altro computer, occorre compilare il supporto alla stampa come modulo, M, per poterlo disattivare quando si vuole fare una connessione PLIP.

64.2 Dispositivi di stampa

I dispositivi di stampa sono le porte parallele e/o seriali utilizzate per la connessione con le stampanti. Il nome assegnato alle porte parallele destinate alla stampa, dipende dell'indirizzo I/O di queste. Segue un elenco degli indirizzi possibili per le porte parallele.

Di solito, la prima porta parallela utilizza l'indirizzo di I/O 0x378 e di conseguenza, quasi sempre, il dispositivo utilizzato per la stampa è /dev/lp1. Ma questo ragionamento non vale più per i kernel 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 alla seguente.

lp1 at 0x0378, (polling)

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. Una azione del genere corrisponde a quello che in ambiente Dos si poteva fare nel modo seguente.

C:> copy /b stampa.prn lpt1

64.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 computer remoti.

Coda di stampa

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


Schema semplificato della gestione della coda di stampa.

Le stampe che si accodano all'interno di una directory di spool ricevono un numero di job che serve per distinguerle. Le stampe accodate sono quindi dei processi di stampa accodati.

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

Server di stampa

La prima copia del daemon lpd si occupa anche di stare in ascolto della porta printer in modo da poter ricevere richieste di stampa da altri computer collegati in rete. L'utilizzo del servizio non è concesso a tutti indiscriminatamente, è necessario che il nome, o l'indirizzo IP del computer che ne fa richiesta sia presente nel file /etc/hosts.equiv ( hosts.equiv), 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.


Lo stesso daemon lpd è il responsabile dell'inserimento in coda dei file da stampare, provenienti da computer remoti.

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

# lpd

lpd [<opzioni>]

È il daemon che si occupa di gestire la coda di stampa, ovvero lo spool 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 normalmente utilizzata 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

/etc/printcap

Contiene la descrizione (e la configurazione) delle stampanti locali e remote. Viene letto una volta da lpd, non appena viene avviato. Per fare in modo che lpd rilegga il suo contenuto (di solito dopo che vi sono state apportate modifiche) è necessario inviargli un segnale SIGHUP.

/etc/hosts.equiv

I computer elencati all'interno di questo file sono ammessi ad utilizzare il servizio di stampa locale.

/etc/hosts.lpd

I computer elencati all'interno di questo file sono ammessi ad utilizzare il servizio di stampa locale.

/etc/hosts.lpd

Questo file serve per elencare i nomi dei computer cui è consentito collegarsi e utilizzare le stampanti del computer locale.

Anche i computer elencati nel file /etc/hosts.equiv sono ammessi ad utilizzare le stampanti locali. Ma questo file riguarda piuttosto il concetto generale della ``equivalenza'', e viene utilizzato soprattutto per consentire l'accesso a programmi come rsh.

In generale quindi, se quello che si vuole è solo concedere l'utilizzo della stampante, è opportuno inserire i nomi di quei computer 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 pippo.zigozago.dg di utilizzare la stampante locale.

pippo.zigozago.dg

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.

$ lpr

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

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

Alcune opzioni

-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 allo spool, elimina il file. Funziona in combinazione con il parametro -s.

-s

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

-#n

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.

$ lpq

lpq [<opzioni>] [<numero-di-job>... ] [<utente>... ]

lpq esamina lo spool 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 job di stampa.

$ lprm

lprm [<opzioni>] [<utente>... ]

Permette di rimuovere uno o più job di stampa precedentemente accodati. 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 job 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-di-job>...

Se tra gli argomenti vengono indicati uno o più numeri, questi si intendono riferiti ai processi di stampa (job) che si vogliono eliminare.

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

Comandi

lpc può essere eseguito anche da un utente normale, ma in tal caso potranno essere eseguite solo alcune funzioni. Segue l'elenco dei 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 daemon di stampa. Ciò può essere utile quando per qualche motivo inspiegabile il daemon ha interrotto la sua attività lasciando dei processi di stampa nella coda.

status { all | <stampante>}

Visualizza lo stato della stampante locale indicata.

---------

I comandi restanti sono riservati all'uso da parte dell'utente root.

---------

abort { all | <stampante>}

Termina l'esecuzione del daemon attivo che si occupa della stampa nel computer locale e quindi disabilita la stampa, prevenendo l'avvio di altri daemon da parte di lpr. Quando verrà riavviata la stampa, verrà ripresa la stampa del processo di stampa attivo nel momento dell'interruzione.

clean { all | <stampante>}

Elimina i file temporanei, di dati e di controllo che non possono essere stampati, cioè quelli che non fanno parte di un job 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 daemon necessari.

stop { all | <stampante>}

Interrompe il daemon di spool 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-di-job>... ] [<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 daemon di stampa se necessario, annullando l'effetto di un precedente comando down.

/etc/pritcap

Il file /etc/printcap è il punto più delicato del sistema di stampa BSD. Dalla sua corretta configurazione dipende il funzionamento delle stampe. Si tratta di un database nel quale ogni record contiene le informazioni per una stampante. I campi di questi record sono separati dal simbolo : e possono essere spezzati su più righe utilizzando il simbolo \ seguito immediatamente da newline (<LF>).

All'interno di questo file si possono trovare le indicazioni di diverse stampanti che possono fare capo a una 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 dal computer paperone.zagozigo.dg
net:\
        :sd=/var/spool/lpd/net:\
        :mx#0:\
        :sh:\
        :rm=paperone.zagozigo.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 eventuale valore.

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

Vedere printcap(5).

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/pritcap 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 computer remoto da utilizzare per la stampa.

rp

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

sd

Spool Directory. Il nome della directory di spool 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.

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.

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=paperone.zagozigo.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 del computer remoto (paperone.zagozigo.dg) e il nome della stampante remota.

Quando si utilizza una stampante remota, nel caso in cui i dati da stampare richiedano una 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 del computer remoto non ha un filtro.

/var/spool/lpd/<stampante>/

Le directory di spool sono definite attraverso il campo sd dei record contenuti in /etc/printcap. Normalmente, nelle distribuzioni 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 e/o in corso di stampa. Al loro interno, durante l'uso del sistema di stampa, si trovano in particolare i file seguenti.

lock

Contiene il numero del processo di stampa (job) in esecuzione.

cf*

Sono i file di controllo con l'indicazione di informazioni sui processi di stampa.

df*

Sono i file contenenti i dati da stampare.

Alle volte si ha difficoltà a eliminare una coda di stampa, cioè a eliminare una stampa. In questi casi, l'amministratore del sistema può semplicemente eliminare 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 in ogni directory di spool da controllare. Questo file deve contenere un numero corrispondente alla quantità di blocchi che si vuole restino comunque liberi.

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

File di testo

Negli ambienti Unix i file di testo (o file ASCII) seguono la convenzione della terminazione di riga attraverso il noto carattere newline corrispondente al codice ASCII <LF>.

Con il sistema operativo Dos è stato introdotto un codice di fine riga differente, corrispondente a <CR><LF>. La maggior parte delle stampanti in circolazione è adatta a quest'ultimo tipo di terminazione 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 la terminazione 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 newline in modo che comprendano sia <CR> che <LF>.

Il tipico programma in grado di eseguire questa conversione è unix2dos, il quale si comporta come programma filtro, e per questo è perfettamente adatto all'utilizzo come filtro di stampa. 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

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.

64.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 un scopo particolare. Di fatto, è preferibile limitarsi ad utilizzarne uno solo, e precisamente quello del campo if, o Input Filter.

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 log: il nome dell'utente e il nome del computer.

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.

Se si fanno modifiche al file /etc/printcap non bisogna poi dimenticare di inviare un segnale di aggancio al daemon lpd per fare in modo che venga riletto: kill -s SIGHUP <pid-di-lpd>.

daniele@topolino.zigozago.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
topolino.zigozago.dg

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

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 ottiene solo una segnalazione di errore: unix2dos non è 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 e dello script utilizzato come filtro.

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

È importante osservare un paio di particolari:

Filtri PostScript

Tutti i filtri di stampa in grado di convertire file PostScript in qualcosa di stampabile senza 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 -sPAGESIZE=a4 -sDEVICE=laserjet -sOutputFile=- -

Problemi

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

In questo caso, si può utilizzare un trucco: il filtro di stampa riceve i dati dallo standard input nel modo solito, li trasforma e, invece di emetterli attraverso lo standard output li invia a un'altra coda di stampa.

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

Filtri sofisticati

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

Anche quando non si è così fortunati, esiste sempre una 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 di spool e i filtri necessari.

64.6 Accessori di stampa

Alcuni programmi sono utili come strumenti per la diagnosi o la configurazione della stampa.

# lptest

lptest [<larghezza>] [<altezza>]

Emette attraverso lo standard output una serie di caratteri utilizzabile per un test 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 un test di stampa utile solo per le stampanti a impatto come quelle ad aghi, a catena, a margherita...

64.7 Stampare attraverso X

Quando si inizia a utilizzare X Window System, 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.


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.


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.

 

1997.10.26 - Scritto da Daniele Giacomini   daniele@calion.com   (vedi copyright: Appunti Linux).


Capitolo successivo Capitolo precedente Indice