Estoy buscando una manera de ver la marca de tiempo de un trabajo en CUPS. He buscado en las páginas de manual y parece que no puedo encontrarlo.
El objetivo a largo plazo es tener un script que analice el tiempo del ID del trabajo y elimine automáticamente cualquier trabajo que tenga más de cierta antigüedad, para evitar sobrecargar el servidor. Mi servidor CUPS tiene más de 2000 colas de impresión.
Respuesta1
Encontré las siguientes 2 preguntas en el sitio de U&L que parecen dar pistas sobre una posible forma de hacer esto. Estas 2 preguntas:
- Ver todos los trabajos de impresión del usuario desde la línea de comando
- ¿Cómo mostrar el historial de trabajos de la impresora CUPS?
Parecería implicar que podrías utilizarlo lpstat
para conseguir lo que deseas. Noté que podía ejecutar este comando:
$ sudo lpstat -W completed
mfc-8480dn-1652 root 1024 Tue 28 Jan 2014 01:19:34 AM EST
Y éste:
$ sudo lpstat -W completed -u saml | head -2
mfc-8480dn-1524 saml 23552 Thu 28 Nov 2013 10:45:44 AM EST
mfc-8480dn-1526 saml 699392 Sat 30 Nov 2013 10:34:34 AM EST
Pero -u all
no hizo nada por mí.
$ sudo lpstat -W completed -u all | head -2
$
Curiosamente podría hacer esto:
$ sudo lpstat -W completed -u saml,root | head -3
mfc-8480dn-1524 saml 23552 Thu 28 Nov 2013 10:45:44 AM EST
mfc-8480dn-1526 saml 699392 Sat 30 Nov 2013 10:34:34 AM EST
mfc-8480dn-1652 root 1024 Tue 28 Jan 2014 01:19:34 AM EST
Entonces, una forma pirateada de hacer esto sería formalizar una lista de usuarios en su sistema y luego agregarla como un subcomando al -u
argumento de esta manera:
$ sudo lpstat -W completed -u $(getent passwd | \
awk -F: '{print $1}' | paste -sd ',')
Sólo para mostrar que esto ve a todos los usuarios localmente, puede obtener una lista única de sus usuarios como esta:
$ sudo lpstat -W completed -u $(getent passwd | \
awk -F: '{print $1}' | paste -sd ',') | awk '{print $2}' | sort -u
ethan
root
sam
tammy
¿Asuntos?
Un problema con esto es que si el usuario que imprime en CUPS no tiene una cuenta local, no se mostrará.
Pero si tiene un directorio que contiene sus archivos de control LPD, normalmente es , you'll notice a bunch of control files in there. These files are kept as a result of the
la configuración /var/spool/cups MaxJobs`, que por defecto es 500 cuando no está configurada.
$ sudo ls -l /var/spool/cups/ | wc -l
502
¿Otra fuente de nombres de usuario?
Si examina estos archivos, notará que contienen nombres de usuario, y no solo los de las cuentas que están presentes en el sistema.
$ strings /var/spool/cups/* | grep -A 1 job-originating-user-name | head -5
job-originating-user-name
tammyB
--
job-originating-user-name
tammyB
Así podríamos seleccionar todas las entradas que contengan el nombre de usuario seguido de la B.
$ sudo strings /var/spool/cups/* | grep -A 1 job-originating-user-name | \
grep -oP '.*(?=B)' | sort -u
ethan
guest-AO22e7
root
sam
saml
slm
tammy
Luego, esta lista se puede adaptar de la misma manera que estábamos usando originalmente para tomar la lista de usuarios getent passwd
, así:
$ sudo lpstat -W completed -u $(strings /var/spool/cups/* | \
grep -A 1 job-originating-user-name | \
grep -oP '.*(?=B)' |sort -u | paste -sd ',')
mfc-8480dn-1525 tammy 545792 Thu 28 Nov 2013 01:36:59 PM EST
mfc-8480dn-1526 saml 699392 Sat 30 Nov 2013 10:34:34 AM EST
mfc-8480dn-1652 root 1024 Tue 28 Jan 2014 01:19:34 AM EST
mfc-8480dn-1672 saml 1024 Sun 09 Feb 2014 01:56:26 PM EST
Referencias
Respuesta2
Tengo otro enfoque quizás más sencillo para limpiar trabajos de impresión antiguos. En lugar de encontrar una manera de convertir las marcas de tiempo abreviadas en los trabajos de impresión, es más fácil usar el comando buscar para realizar la tarea de eliminar trabajos de impresión antiguos que cumplan con ciertos criterios. Por ejemplo, si desea buscar trabajos de impresión con más de 4 días de antigüedad:
find /var/spool/cups -name "*-001" -mtime +4
Todos los trabajos de impresión activos en cups tienen archivos /var/spool/cups
con la extensión -001
. Después de eso, sólo es cuestión de utilizar su herramienta de manipulación de cadenas favorita para obtener el número de trabajo de impresión real de la salida.
Respuesta3
En realidad, ignore todo esto por completo y no se moleste en intentar obtener la fecha de la lista de trabajos. No es necesario,a menos que necesite una marca de tiempo precisa del trabajo de impresión (e incluso entonces, no se desprende inmediatamente del resultado o del manual de lpstat si la fecha y hora dada es de cuando se envió el trabajo o cuando se completó).
No necesita hacerlo en absoluto porque simplemente puede generar una marca de fecha de "ahora" en el momento en que detecte su trabajo en la lista de trabajos "completados".
._. printJob=$(lp somefile | awk '{print $4}')
._. printJobCompleted=$(lpstat -W "completed" | grep $printJob )
._. printedDatestamp=$(date +%s)
Aunque, por supuesto, no se puede saber que el trabajo está completado hasta que lo esté. Por lo tanto, es posible que desee realizar un bucle y dormir hasta que detecte que lo es.
Si desea la fecha que está en la cola, quizás haga algo como esto:
Capture su identificación del trabajo de impresión cuando envíe la instrucción para imprimir:
._. printJob=$(lp somefile | awk '{print $4}')
._. echo $printJob
Kyocera-ECOSYS-P5021cdw-564
(Es necesario analizar la salida de lp a través de awk porque parece que lp no tiene opción para simplemente devolver el trabajo de impresión):
._. lp somefile
request id is Kyocera-ECOSYS-P5021cdw-568 (1 file(s))
( awk '{print $4}'
obtiene la cuarta palabra de esa cadena de salida).
Luego use lpstat para obtener los detalles del trabajo completo:
._. lpstat -W "completed" | grep $printJob
Kyocera-ECOSYS-P5021cdw-564 ming 2048 Sun 18 Apr 2021 11:20:56 BST
Aislar esa parte que incluye la fecha es un poco incómodo, porque lpstat parece ofrecer ahora una forma directa de hacerlo, y la fecha consta de varias palabras. Entonces quizás cualquiera de las dos:
._. printJobDateString=$(lpstat -W "completed" | grep $printJob | awk '{print $4,$5,$6,$7,$8,$9}')
._. echo $printJobDateString
Sun 18 Apr 2021 11:20:56 BST
(Y awk tampoco parece ofrecer una forma de capturar un rango; corríjame si me equivoco).
... o hacer lo mismo con el shell incorporado read
, que, por razones que desconozco, trata toda la cadena de fecha como una sola palabra (la cuarta palabra en la cadena de salida, donde leer marca las primeras cuatro palabras con los nombres a,b,c,d):
._. printJobDateString=$(lpstat -W "completed" | grep $printJob | while read a b c d; do echo "$d"; done)
._. echo $printJobDateString
Sun 18 Apr 2021 11:20:56 BST
Finalmente, tal vez conviértalo en una marca de fecha de segundos desde la época, para facilitar la comparación:
._. printedDatestamp=$(date --date="$printJobDateString" +%s)
._. echo $printedDatestamp
1618741256
printJobDateString estará vacío si lpstat no tenía ningún registro del trabajo en su lista completa. En ese caso, la fecha asumirá que es 1/1/1970 cuando la convierta a segundos de época.
Aunque en realidad, puede ser bastante improbable que su trabajo de impresión no termine en la lista de trabajos "completados", porque esa lista parece recopilar tanto trabajos cancelados como trabajos completados.Así que ignora la advertencia a continuación.. Ja.
Pero ten cuidado, si lpstat no tiene su trabajo de impresión, devolverá una cadena vacía. Y si introduce "fecha" con una cadena vacía, mostrará la fecha de hoy. Y si tiene eso en un guión, podría inducirle a pensar que el trabajo se ha completado, porque le dará la fecha de hoy.
Por ejemplo:
._. date -d @$(date --date="" +%s) +"%F %T %z"
2021-04-17 00:00:00 +0100
Mientras que, 'fecha' toma 0 como el inicio de la 'época' de Unix (el amanecer del tiempo maravilloso) - 1 de enero de 1970:
._. date -d @0 +"%F %T %z"
1970-01-01 01:00:00 +0100
Esto podría indicar más útilmente un trabajo no completado que la fecha de hoy. Así que convierta la cadena vacía a cero (si obtiene uno) antes de enviarla a 'fecha', tal vez así:
._. emptyString=""
._. zero=$( [[ -z "$emptyString" ]] && echo 0 || echo "$emptyString" )
._. echo zero
0
En otras palabras, genere la marca de fecha de esta manera:
._. printedDatestamp=$(date --date="$( [[ -z "$printJobDateString" ]] && echo 0 || echo "$printJobDateString" )" +%s)
Finalmente, todos los pasos juntos:
._. printJob=$(lp -P "1-4" -o fit-to-page -o number-up=2 -o sides=two-sided-short-edge -o KCEcoprint=On "$fn" | awk '{print $4}')
._. printJobDateString=$(lpstat -W "completed" | grep $printJob | while read a b c d; do echo "$d"; done)
._. printedDatestamp=$(date --date="$( [[ -z "$printJobDateString" ]] && echo 0 || echo "$printJobDateString" )" +%s)
PD
Úselo sleep
también, después de enviar el trabajo de impresión, en un bucle que continúa hasta que obtenga una cadena vacía, colocando su printJob sobre la salida de lpstat -W "not-completed"
. Sólo entonces encuesta lpstat -W "completed"
.
Allí: la marca de tiempo de un trabajo de impresión. ¿Y quién dijo que el control de impresión de Linux era humano? Nadie. Nadie dijo tal cosa. Y todo lo que dijeron al respecto lo murmuraron en voz baja.