Estou procurando uma maneira de visualizar o carimbo de data/hora de um trabalho no CUPS. Eu procurei nas páginas de manual e não consigo encontrá-lo.
O objetivo de longo prazo é ter um script que analise o horário do jobID e exclua automaticamente qualquer trabalho que tenha ultrapassado uma determinada idade - para evitar sobrecarregar o servidor. Meu servidor CUPS tem mais de 2.000 filas de impressão.
Responder1
Encontrei as duas perguntas a seguir no site da U&L que parecem dar dicas sobre uma possível maneira de fazer isso. Estas 2 perguntas:
- Veja todos os trabalhos de impressão do usuário na linha de comando
- Como mostrar o histórico de trabalhos da impressora CUPS?
Parece implicar que você poderia usar lpstat
para conseguir o que deseja. Percebi que poderia executar este comando:
$ sudo lpstat -W completed
mfc-8480dn-1652 root 1024 Tue 28 Jan 2014 01:19:34 AM EST
E este:
$ 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
Mas -u all
não fez nada por mim.
$ sudo lpstat -W completed -u all | head -2
$
Curiosamente eu poderia fazer isso:
$ 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
Portanto, uma maneira hackeada de fazer isso seria formalizar uma lista de usuários em seu sistema e adicioná-la como um subcomando ao -u
argumento da seguinte forma:
$ sudo lpstat -W completed -u $(getent passwd | \
awk -F: '{print $1}' | paste -sd ',')
Apenas para mostrar que todos os usuários são vistos localmente, você pode obter uma lista exclusiva de seus usuários da seguinte forma:
$ sudo lpstat -W completed -u $(getent passwd | \
awk -F: '{print $1}' | paste -sd ',') | awk '{print $2}' | sort -u
ethan
root
sam
tammy
Problemas?
Um problema com isso é que se o usuário imprimindo no CUPS não tiver uma conta local, eles não serão exibidos.
Mas se você tiver um diretório que contém seus arquivos de controle LPD, normalmente é , you'll notice a bunch of control files in there. These files are kept as a result of the
a configuração /var/spool/cups MaxJobs`, cujo padrão é 500 quando não definido.
$ sudo ls -l /var/spool/cups/ | wc -l
502
Outra fonte de nomes de usuário?
Se você examinar esses arquivos, notará que eles contêm nomes de usuários, e não apenas nomes de contas presentes no sistema.
$ strings /var/spool/cups/* | grep -A 1 job-originating-user-name | head -5
job-originating-user-name
tammyB
--
job-originating-user-name
tammyB
Assim, poderíamos selecionar todas as entradas que contêm o nome de usuário seguido do 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
Esta lista pode então ser adaptada da mesma forma que usamos originalmente para obter a lista de usuários de getent passwd
, assim:
$ 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
Referências
Responder2
Tenho outra abordagem talvez mais simples para limpar trabalhos de impressão antigos. Em vez de encontrar uma maneira de converter os carimbos de data/hora abreviados nos trabalhos de impressão, é mais fácil usar o comando find para realizar a tarefa de excluir trabalhos de impressão antigos que atendam a determinados critérios. Por exemplo, se você quiser encontrar trabalhos de impressão com mais de 4 dias:
find /var/spool/cups -name "*-001" -mtime +4
Todos os trabalhos de impressão ativos no cups possuem arquivos /var/spool/cups
com a extensão -001
. Depois disso, é apenas uma questão de usar sua ferramenta favorita de manipulação de strings para obter o número real do trabalho de impressão na saída.
Responder3
Na verdade, ignore tudo isso completamente e nem se preocupe em tentar obter a data na lista de empregos. Você não precisa,a menos que você precise de um carimbo de data e hora preciso do trabalho de impressão (e mesmo assim, não é imediatamente aparente na saída ou no manual do lpstat se a data e hora fornecida é de quando o trabalho foi enviado ou quando foi concluído).
Você não precisa fazer isso porque você pode apenas gerar um carimbo de data de 'agora' no momento em que detecta seu trabalho na lista de trabalhos "concluídos".
._. printJob=$(lp somefile | awk '{print $4}')
._. printJobCompleted=$(lpstat -W "completed" | grep $printJob )
._. printedDatestamp=$(date +%s)
Embora, é claro, você não possa dizer que o trabalho está concluído até que esteja concluído. Então você pode querer fazer um loop e dormir até detectar que sim.
Se você quiser a data que está na fila, talvez faça algo assim:
Capture o ID do seu trabalho de impressão ao enviar a instrução para imprimir:
._. printJob=$(lp somefile | awk '{print $4}')
._. echo $printJob
Kyocera-ECOSYS-P5021cdw-564
(É necessário analisar a saída do lp através do awk porque parece que o lp não tem opção de simplesmente retornar o trabalho de impressão):
._. lp somefile
request id is Kyocera-ECOSYS-P5021cdw-568 (1 file(s))
( awk '{print $4}'
get é a quarta palavra dessa string de saída).
Em seguida, use lpstat para obter os detalhes do trabalho concluído:
._. lpstat -W "completed" | grep $printJob
Kyocera-ECOSYS-P5021cdw-564 ming 2048 Sun 18 Apr 2021 11:20:56 BST
Isolar a parte que inclui a data é um pouco estranho, porque o lpstat parece oferecer agora uma maneira direta de fazer isso, e a data consiste em várias palavras. Então, talvez:
._. printJobDateString=$(lpstat -W "completed" | grep $printJob | awk '{print $4,$5,$6,$7,$8,$9}')
._. echo $printJobDateString
Sun 18 Apr 2021 11:20:56 BST
(E o awk também não parece oferecer uma maneira de capturar um intervalo - corrija-me se eu estiver errado).
... ou faça o mesmo com o shell built-in read
, que, por razões que não conheço, trata toda a sequência de datas como uma única palavra (a quarta palavra na sequência de saída, onde read marca as primeiras quatro palavras com os nomes 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, talvez transforme-o em um carimbo de data de segundos desde a época, para facilitar a comparação:
._. printedDatestamp=$(date --date="$printJobDateString" +%s)
._. echo $printedDatestamp
1618741256
printJobDateString estará vazio se lpstat não tiver nenhum registro do trabalho em sua lista concluída. Nesse caso, a data assumirá que é 01/01/1970 quando você a converte em segundos de época.
Na verdade, porém, pode ser bastante improvável que o seu trabalho de impressão não acabe na lista de trabalhos "concluídos", porque essa lista parece coletar trabalhos cancelados, bem como trabalhos concluídos.Então ignore o aviso abaixo. Ah.
Cuidado, se lpstat não tiver seu trabalho de impressão, ele retornará uma string vazia. E se você alimentar 'data' com uma string vazia, ela exibirá a data de hoje. E se você tiver isso em um script, poderá induzi-lo a pensar que o trabalho foi concluído, porque lhe dará a data de hoje.
Por exemplo:
._. date -d @$(date --date="" +%s) +"%F %T %z"
2021-04-17 00:00:00 +0100
Considerando que 'data' leva 0 para ser o início da 'época' Unix (o amanhecer do tempo legal) - 1º de janeiro de 1970:
._. date -d @0 +"%F %T %z"
1970-01-01 01:00:00 +0100
Isto pode indicar de forma mais útil um trabalho não concluído do que a data de hoje. Portanto, transforme a string vazia em zero (se você conseguir um) antes de alimentá-la para 'data', talvez assim:
._. emptyString=""
._. zero=$( [[ -z "$emptyString" ]] && echo 0 || echo "$emptyString" )
._. echo zero
0
Em outras palavras, gere o carimbo de data assim:
._. printedDatestamp=$(date --date="$( [[ -z "$printJobDateString" ]] && echo 0 || echo "$printJobDateString" )" +%s)
Finalmente, todas as etapas juntas:
._. 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)
PS
Use sleep
também, após enviar o trabalho de impressão, em um loop que continua até obter uma string vazia, colocando seu printJob sobre a saída de lpstat -W "not-completed"
. Só então enquete lpstat -W "completed"
.
Pronto: o carimbo de data/hora de um trabalho de impressão. E quem foi que disse que o controle de impressão do Linux era humano? Ninguém. Ninguém disse tal coisa. E tudo o que diziam sobre isso, murmuravam baixinho.