Acerca de impresoras:

Extraído del Printer HowTo de Grant Taylor y Brian McCauley

Todo sistema que se precie es capaz de gestionar una o varias impresoras, con uno o varios usuarios, que les envían distintas clases de documentos, más o menos dignamente. Un*x resuelve estos problemas mediante un conjunto de programas, los servidores de impresión, que gestionan los trabajos pendientes, y los encauzan a las impresoras adecuadas, todo de manera completamente transparente al usuario. El camino más corto en Un*x (y GNU/Linux), es enviar los datos a imprimir directamente al dispositivo adecuado. El siguiente comando envía un listado del directorio a la impresora en puerto paralelo (hablando en DOS, LPT1:)

[root#pantano:~]# ls > /dev/lp1

El problema de este método es que no aprovecha las capacidades de multitarea de Linux, debido a que el tiempo que tarda el comando en completarse será el mismo que emplee la impresora en despachar el trabajo. En una impresora lenta, o en una apagada o sin papel, puede prolongarse un poco. Podríamos ejecutar el comando simplemente en segundo plano, pero no adelantaríamos mucho. Además, deberá tener privilegios de root. Un remedio mejor es crear un área de spool, es decir, guardar los datos a imprimir en un fichero temporal, y arrancar un proceso en segundo plano que envíe los datos a la impresora, y gestione las incidencias que se presenten. Esencialmente, así funciona el sistema de impresión en Linux. Para cada impresora, se define un área spool, donde cada trabajo pendiente se almacena en un fichero. Un proceso en segundo plano (llamado el demonio de impresión) analiza metódica y constantemente los ficheros spool, buscando nuevos datos a imprimir. Cuando aparece alguno, son enviados a la impresora apropiada; cuando más de un fichero está a la espera, se colocan en una cola (el primero que entra es el primero que se procesa), por lo que se habla propiamente de la "cola de impresión".

En el caso de impresión remota, los trabajos se gestionan localmente, como cualquier otro, pero el demonio de impresión lo envía a través de la red hacia el ordenador o impresora destino. La información que el demonio de impresión necesita para su trabajo (el dispositivo físico, el spool de datos, la máquina e impresora remota, etc.) se almacenan en un fichero llamado /etc/printcap, que describiremos más tarde.

En lo sucesivo, el término "impresora" se referirá a una máquina lógica definida en /etc/printcap. El concepto "impresora física", define la cosa que mancha papel. Es perfectamente posible describir múltiples entradas en /etc/printcap que se refieren a una sola impresora física, pero por caminos tortuosos. No nos preocupemos, lo aclararemos al describir printcap.

Lo primero a tener en cuenta

El sistema de impresión de Linux se sustenta en cinco programas, que deberían estar donde aparecen en el siguiente listado, propiedad de root, y grupo lp (o daemon, según el sistema en concreto)

-rwxr-xr-x  root lp    /bin/lpr
-rwxr-xr-x  root lp    /bin/lpq
-rwxr-xr-x  root lp    /bin/lpc
-rwxr-xr-x  root lp    /bin/lprm
-rwxr-x---  root lp    /sbin/lpd

Los cuatro primeros tienen por fin enviar, cancelar y examinar los trabajos de impresión. /sbin/lpd es el demonio de impresión. Hay páginas de manual que explican con detalle todas estas órdenes y que debería consultar para ampliar información.

Importante

Los directorios, permisos y propiedad de los ficheros pueden diferir a los de su sistema, aunque no deberían ser MUY distintos.

Es importante saber que, por defecto, lpr, lprm, lpc y lpq trabajan con una impresora llamada "lp". Si define la variable de entorno PRINTER con el nombre de una impresora, pasará a ocupar el valor por defecto. Se puede indicar sobre la marcha una impresora distinta con la opción -P impresora en la línea de órdenes.

Los directorios fundamentales.

Realmente, sólo hay un directorio importante: el área de spool donde se almacenan los datos a la espera de que lpd decida qué hacer con ellos. Sin embargo, un sistema típico debería configurarse en varios directorios, uno para cada impresora, lo que facilita notablemente el mantenimiento. En la mayoría de las instalaciones, /var/spool/lpd es el directorio spool principal, y cada impresora tiene un subdirectorio particular, con el mismo nombre que la impresora. Así, si tiene una impresora llamada PJL-16 que admite PostScript y HPGL, debería crear dos directorios, por ejemplo /var/spool/lpd/PJL-16-ps y /var/spool/lpd/PJL-16-hpgl.

Los directorios temporales deberían pertenecer a root, grupo lp; user y group deben poder leer y escribir, y el resto, leer (permiso 0775). Para cada directorio de impresora, la orden adecuada es

[root#pantano:~]# chmod ug=rwx,o=rx PJL-16-ps
[root#pantano:~]# chgrp lp PJL-16-ps

O, en otra notación

[root#pantano:~]# chmod 775 PJL-16-ps
[root#pantano:~]# chown .lp PJL-16-ps

Los destinos, permisos y propietarios aquí indicados deben considerarse como indicativos, pues pueden variar entre distintos sistemas e instalaciones.

Además de los programas ya tratados, cada directorio temporal debe contener como mínimo cuatro ficheros, .seq , errs , lock y status, y deberán tener permisos 0664. El fichero .seq contiene la secuencia de trabajos enviados. status contiene el mensaje que devuelve "lpc stat". El fichero lock impide al lpd imprimir al tiempo dos trabajos en la misma impresora, y errs guarda un registro de los fallos de la impresora. El fichero errs es actualmente potestativo, y ahora puede llamarse como le apetezca. Su nombre se especificará en /etc/printcap. Debe, sin embargo, existir un fichero que permita a lpd registrar los mensajes de error.

/etc/printcap

/etc/printcap es un fichero texto, modificable con su editor favorito. Su propietario debe ser root y debe tener permisos 0644.

Aunque a golpe de vista parezca tan comprensible como la piedra Rosetta, su estructura es muy sencilla y asequible. Parte de la mala fama se debe a que algunas distribuciones no incluyen página de manual para printcap, y el hecho de que muchos printcap están generados por programas, o por gente cuya manera de despreciar al género humano es omitir comentarios que ayuden a su comprensión. Desde aquí hacemos un llamamiento para que su fichero printcap sea tan legible como sea posible.

Cada entrada de printcap describe una impresora. Mejor aún, cada entrada de printcap provee una denominación lógica para un dispositivo físico, y describe cómo deben los datos ser enviados y manejados por él.

Por ejemplo, una entrada de printcap definirá qué puerto vamos a usar, qué directorio spool, qué proceso deben soportar los datos, qué clase de errores debemos notificar, qué volumen de datos se permiten enviar como máximo, o limitar el acceso de ciertos dispositivos.

Además, podemos definir distintos modos de procesar datos para una misma impresora. Por ejemplo, una misma impresora de HP puede manejar datos en formatos PostScript, HPGL y PCL, dependiendo de la secuencia de órdenes que le enviamos al comienzo de cada trabajo. Tendría sentido definir los tres modos de trabajo como sendas impresoras, cada una de las cuales procesará los datos dependiendo del modo de trabajo. Los programas que generan datos ps se enviarán a la impresora PS, los dibujos HPGL a la impresora HPGL, y así sucesivamente. Llamaremos "filtros" a los programas que procesan los datos a imprimir. Un filtro puede incluso no enviar ningún dato al puerto.

Un ejemplo típico de entrada en /etc/printcap podría ser

# Ejemplo de printcap con dos alias impresora
HP|HP850C:\
# lp es el dispositivo de impresión, en este caso,
# la primera impresora
:lp=/dev/lp1:\
# sd indica el directorio spool
:sd=/var/spool/lpd/HP850C:

Como vemos, cada entrada de /etc/printcap se estructura en una serie de campos, encabezados por una etiqueta, y limitados por dos puntos, a excepción del primer campo, que describe la impresora. Los campos pueden tener tres tipos de valores: texto, lógico y numérico, en los que nos extenderemos más adelante. La primera línea de la entrada determina el nombre y alias de la impresora. La impresora por defecto debería llamarse "lp"; por ejemplo, si la impresora del ejemplo anterior es la única que tenemos, la primera línea sería

# Ejemplo para la impresora por defecto
lp|HP850C:\

Importante

Sólo podemos tener una impresora llamada "lp".

Podemos usar el nombre que nos apetezca como "La Picadora de papel del despacho de Gertrudis", aunque no parezca quizá muy práctico. Los siguientes campos son los más comunes, y los más importantes:

Tabla 1. Campos en /etc/printcap

CampoTipoDescripción
lpTextoDispositivo de impresión (ej. /dev/lp1)
sdTextoNombre del directorio tampon de esta impresora
lfTextoFichero que almacena el registro de errores
ifTextoNombre del filtro de entrada
rmTextoNombre del host de impresion remota
rpTextoNombre de la impresora remota
shLógicoSuprime las páginas que separan los trabajos
sfLógicoSuprime las paginas en blanco al final del trabajo
mxNuméricoTamaño máximo del trabajo de impresión (en bloques)

Veamos ahora estos campos con un poco más de detalle.

lp

Apunta al puerto/dispositivo de impresión. Si especificamos /dev/null como dispositivo, el resto de los procesos se ejecutan normalmente, pero los datos de salida van a parar al inodoro. No se utiliza a excepción de las pruebas de configuración del dispositivo. Cuando configure una impresora remota con los campos rm y rp , debería poner ":lp=:" en /etc/printcap, indicando que no está asignada a ningún dispositivo local.. No deje este campo en blanco a menos que use una impresora remota, o el demonio de impresión se quejará amargamente, si no especifica un dispositivo de impresión.

lf

Guarda un registro de los errores de impresión. Cualquier fichero que especifique deberá existir antes de su uso, o no se registrarán las incidencias.

if

Indica el nombre del filtro de impresión a ejecutar. Los filtros son programas que reciben datos por la entrada estándar, y los devuelven procesados por la salida estándar. Un empleo típico es detectar texto llano y convertirlo en PostScript para imprimirlo en ese tipo de trastos. Son muy útiles, por ejemplo, para eliminar el efecto escalera, o cambiar la página de códigos sin necesidad de cambiar la configuración de la impresora cada vez que la usemos entre UNIX y DOS. Cuando se especifica un filtro de entrada, el demonio de impresión no envía los datos pendientes al dispositivo especificado. En su lugar, arranca el filtro y asigna el fichero temporal a la entrada estándar, y el dispositivo de impresión como salida estándar.

rm y rp

Controlan el destino de la impresión remota. Enviar el documento a imprimir a una impresora remota es tan fácil como indicar el anfitrión en rm, la impresora correspondiente en rp, y asegurarse que lp está vacío. Fíjese en que los datos se tamponan localmente antes de ser enviados, y que le ejecutará cualquier filtro que especifique. Una entrada típica de /etc/printcap en la máquina local (pera.huerta.net) para trabajar sobre la impresora picapapel, en la estación rábano.huerta.net (remota), sería:

picapapel::lp=::rm=rábano.huerta.net::rp=picapapel:\
:sd=/var/spool/lpd/picapapel:

En la máquina remota necesitará que /etc/hosts.equiv o /etc/hosts.lpd contenga la línea pera.huerta.net; Tenga cuidado con los permisos de acceso.

sh y sf

Portadillas y separadores. Salvo que haya mucha gente distinta usando su impresora, probablemente no estará interesado en las páginas separadoras de trabajos. Las páginas de fin de trabajo son particularmente molestas cuando se trabaja con procesadores de texto, que componen páginas completas, por lo que si especificamos sf, tendremos al final de cada trabajo una página en blanco. sf es muy útil, sin embargo, si usamos la impresora para listar directorios, ficheros en crudo ..., asegurándonos que el trabajo sale completo de la impresión. Se puede presentar un problema si tenemos una impresora PostScript, al quedar residente el último tipo de letra utilizado. Con el campo :tr: lo evitaremos. Es preferible en estos casos dejar :sh:, y que sean los filtros quienes se encarguen de generar las portadillas.

mx

Limita el tamaño del spool de datos, señalando una cantidad en bloques de 1 K ( 1024 bits ). Si mx=0, el límite viene dado por el espacio disponible en disco. Recuerde que lo que limitamos es el tamaño del spool, no la cantidad de datos impresos. Si intentamos sobrepasar el límite, el fichero simplemente se trunca, y el usuario recibe el mensaje

lpr: fichero: copy file is too large.

mx es útil si tiene programas que accidentalmente pueden generar un volumen desproporcionado de datos a imprimir (imágenes, por ejemplo); para impresoras ps, no suele tener mucho interés, pues un volumen pequeño de datos en formato ps pueden generar una notable cantidad de papel impreso. Podemos sustituir el límite de mx escribiendo en cada directorio spool un fichero llamado minfree que contiene el espacio mínimo disponible que permita aceptar trabajos, en forma de fichero texto con el número de bloques mínimos disponibles. Normalmente, suele ser un enlace con el original en /var/spool/lpd, ya que es inusual que cada impresora deba tener un mínimo diferente.

Probemos ahora /etc/printcap con un ejemplo. El siguiente guión de shell es un filtro de entrada muy simple. Sólo encadena su entrada al final de un fichero en /tmp, tras una pancarta adecuada. Usaremos este filtro en el campo if, y enviaremos los datos a /dev/null, ahorrándonos las quejas del demonio especificando un dispositivo de impresión.

#!/bin/sh
# Este filtro debera colocarse en el directorio tampon,
# con el nombre filtro_entrada, propiedad de root,
# grupo lp y permisos 0755
#
echo -------------------------------------->/tmp/testlp.out
date >> /tmp/testlp.out
echo -------------------------------------->>/tmp/testlp.out
cat

Y aquí tenemos nuestra flamante entrada en /etc/printcap. Vea que el formato es razonablemente inteligible, usando caracteres de continuación de línea "\" al final de cada una, excepto la última (de hecho, cada entrada en /etc/printcap es una sola línea)

impre|PLJ-H1998:\
      :lp=/dev/null:\
      :sd=/var/spool/lpd/PLJ-H1998:\
      :lf=/var/spool/lpd/PLJ-H1998/errores:\
      :if=/var/spool/lpd/PLJ-H1998/filtro_entrada:\
      :mx#0:\
      :sh:\
      :sf:

Importante

No deje espacios en blanco, o no funcionará (le aparecerán impresoras sin nombre, no logrará volcar los trabajos, y se acumularán en cola generosamente)

Ahora, hagamos que esto trabaje

  1. DEBE SER EL SUPERUSUARIO (root), tanto si le gusta como si no.

  2. Compruebe los permisos y situaciones de lpr, lprm, lpc, lpq y lpd.

  3. Cree el directorio spool de su impresora: (recuerde que el propietario debe ser root, el grupo lp, y los permisos 0775 con las órdenes

    mkdir /var/spool/lpd /var/spool/lpd/impre
    chown root.lp /var/spool/lpd /var/spool/lpd/impre
    chmod ug=rwx,o=rx /var/spool/lpd /var/spool/lpd/impre
  4. En el directorio spool cree los ficheros necesarios, con los debidos permisos y propietarios

    cd /var/spool/lpd/impre
    touch .seq errores status lock
    chown root.lp .seq errs status lock
    chmod ug=rw,o=r .seq errs status lock
  5. Cree el script filtro de entrada en el directorio spool. Use por ahora el filtro de prueba anterior. Asegúrese que el fichero pertenece a root.lp, y es ejecutable para todos.

  6. Cree el fichero /etc/printcap tal y como lo hemos descrito en el punto anterior. Su propietario será root y sus permisos 0644.

  7. Compruebe que rc.local (normalmente en /etc/rc.d/) contiene la línea /sbin/lpd, y añádala si no está. Esto hace que arranque el demonio de impresión al arrancar. De todos modos puede arrancarlo a mano con la orden lpd.

  8. Haga una prueba: cruce los dedos y teclee

    ls -l | lpr -Pimpre
  9. Busque en /tmp un fichero llamado testlp.out. Debería contener un listado del directorio, con un encabezado.

  10. Si ha funcionado (y no dudamos que habrá sido así), edite /etc/printcap, y copie la entrada de prueba en el mismo fichero. En la primera entrada, cambie el nombre de la impresora a testlp, o el que usted prefiera, pero que no use como nombre real de impresora. En la segunda entrada (que ahora será la de su impresora real), cambie el contenido de lp=/dev/null al del puerto de impresora (normalmente será /dev/lp1) de su ordenador, salvo que vaya a utilizar una impresora remota, en cuyo caso deberá definir rm y rp. Cambie el nombre del filtro if si tiene ya uno previsto, o suprímalo si no va a utilizar ninguno.

  11. Reinicie el sistema, o mate el demonio de impresión y arránquelo, ya que lpd sólo lee /etc/printcap al comenzar su trabajo.

  12. Haga una prueba, y aprecie lo bien que funciona su impresora.

Para añadir nuevas impresoras, sólo tendrá que repetir la entrada de printcap, con las modificaciones pertinentes a cada dispositivo.

Impresión remota e impresión local

La impresión remota nos permite enviar trabajos de impresión desde una máquina, hacia otra (computadora/impresora) conectada a una red; por ejemplo, nuestro equipo funciona de servidor en una red, o si una impresora asignada a nuestra máquina debe ser accesible por otros ordenadores.

Imprimimos localmente cuando usuarios de nuestra máquina envían trabajos a una impresora conectada directamente a la misma.

Como primer paso, cualquier máquina que intente imprimir en su sistema, debe estar registrada en cualquiera de los ficheros /etc/hosts.equiv o /etc/hosts.lpd, que son simples ficheros de texto, con un nombre de maquina por línea. Es preferible el segundo, reservando el primero para proporcionar mayores permisos de acceso, lo que debería ser evitado en lo posible.

Puede restringirse el uso tanto por nombre como por grupos. Especifique los grupos autorizados con uno o varios campos :rg: en /etc/printcap. :rg=admin: sólo autorizará el acceso a la impresora a los usuarios asignados al grupo admin. Puede también limitar el acceso a aquellos usuarios con cuenta en su sistema utilizando el campo lógico :rs:.

La configuración en el sistema cliente sería la siguiente

lp|Remote printer entry:\
      :lp=/dev/null\
      :rm=192.168.1.1:# Aquí puede ir también  el  nombre  del
                      #servidor de impresión.
      :rp=lp:\
      :sd=/var/spool/lpd/remote:\
      :mx#0:\
      :sh: