Просмотр временной метки для заданий печати CUPS

Просмотр временной метки для заданий печати CUPS

Я ищу способ просмотреть временную метку задания в CUPS. Я искал на страницах man и не могу найти.

Долгосрочная цель — иметь скрипт, который анализирует время из jobID и автоматически удаляет любое задание, которое старше определенного возраста, чтобы избежать перегрузки сервера. На моем сервере CUPS более 2000 очередей печати.

решение1

Я нашел следующие 2 вопроса на сайте U&L, которые, как мне кажется, дают подсказки о возможном способе сделать это. Эти 2 вопроса:

Кажется, подразумевается, что вы можете использовать, lpstatчтобы получить то, что вы хотите. Я заметил, что я могу запустить эту команду:

$ sudo lpstat -W completed
mfc-8480dn-1652         root              1024   Tue 28 Jan 2014 01:19:34 AM EST

И этот:

$ 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

Но -u allмне это ничего не дало.

$ sudo lpstat -W completed -u all | head -2
$

Любопытно, что я мог бы сделать это:

$ 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

Поэтому один из хакерских способов сделать это — формализовать список пользователей в вашей системе, а затем добавить его в качестве подкоманды к -uаргументу, например так:

$ sudo lpstat -W completed -u $(getent passwd | \
    awk -F: '{print $1}' | paste -sd ',')

Чтобы показать, что здесь отображаются все пользователи локально, вы можете получить уникальный список ваших пользователей следующим образом:

$ sudo lpstat -W completed -u $(getent passwd | \
    awk -F: '{print $1}' | paste -sd ',') | awk '{print $2}' | sort -u
ethan
root
sam
tammy

Проблемы?

Одна из проблем заключается в том, что если у пользователя, печатающего в CUPS, нет локальной учетной записи, то он не будет отображаться.

Но если у вас есть каталог, содержащий файлы управления LPD, то обычно это , you'll notice a bunch of control files in there. These files are kept as a result of theнастройка MaxJobs в /var/spool/cups, которая по умолчанию равна 500, если не задана.

$ sudo ls -l /var/spool/cups/ | wc -l
502

Еще один источник имен пользователей?

Если вы посмотрите эти файлы, то заметите, что они содержат имена пользователей, а не только имена учетных записей, присутствующих в системе.

$ strings /var/spool/cups/* | grep -A 1 job-originating-user-name | head -5
job-originating-user-name
tammyB
--
job-originating-user-name
tammyB

Таким образом, мы можем выбрать все записи, содержащие имя пользователя, за которым следует буква 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

Затем этот список можно адаптировать таким же образом, как мы изначально использовали для получения списка пользователей из getent passwd, например так:

$ 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

Рекомендации

решение2

У меня есть другой, возможно, более простой подход к очистке старых заданий печати. ​​Вместо того, чтобы искать способ конвертировать сокращенные временные метки в заданиях печати, проще использовать команду find для удаления старых заданий печати, соответствующих определенным критериям. Например, если вы хотите найти задания печати старше 4 дней:

find /var/spool/cups -name "*-001" -mtime +4

Все активные задания печати в cups имеют файлы /var/spool/cupsс расширением -001. После этого вам останется только использовать ваш любимый инструмент для работы со строками, чтобы извлечь из вывода фактический номер задания печати.

решение3

На самом деле, полностью игнорируйте все это, и вообще не пытайтесь получить дату из списка заданий. Вам не нужно,если только вам не нужна точная временная метка задания печати (и даже в этом случае из выходных данных или руководства lpstat не сразу становится ясно, относится ли указанная дата и время к моменту отправки задания или к моменту его завершения).

Вам вообще не нужно этого делать, поскольку вы можете просто сгенерировать метку даты «сейчас» в тот момент, когда обнаружите свою работу в списке «завершенных» работ.

._. printJob=$(lp somefile | awk '{print $4}')
._. printJobCompleted=$(lpstat -W "completed" | grep $printJob )
._. printedDatestamp=$(date +%s)

Хотя, конечно, вы не можете сказать, что работа завершена, пока она не будет выполнена. Так что вы можете зациклиться и спать, пока не обнаружите, что она выполнена.

Если вам нужна дата, которая стоит в очереди, возможно, стоит сделать что-то вроде этого:

При отправке инструкции на печать запишите идентификатор задания на печать:

._. printJob=$(lp somefile | awk '{print $4}')
._. echo $printJob
Kyocera-ECOSYS-P5021cdw-564

(Необходимо проанализировать вывод lp через awk, поскольку, похоже, у lp нет возможности просто вернуть задание печати):

._. lp somefile
request id is Kyocera-ECOSYS-P5021cdw-568 (1 file(s))

( awk '{print $4}'get — четвертое слово этой выходной строки).

Затем используйте lpstat, чтобы получить сведения о выполненном задании:

._. lpstat -W "completed" | grep $printJob
Kyocera-ECOSYS-P5021cdw-564 ming             2048   Sun 18 Apr 2021 11:20:56 BST

Выделение той части, которая включает дату, немного неудобно, потому что lpstat, похоже, предлагает теперь прямой способ сделать это, а дата состоит из нескольких слов. Так что, возможно, либо:

._. printJobDateString=$(lpstat -W "completed" | grep $printJob | awk '{print $4,$5,$6,$7,$8,$9}')

._. echo $printJobDateString
Sun 18 Apr 2021 11:20:56 BST

(И awk, похоже, не предлагает способа захвата диапазона — пожалуйста, поправьте меня, если я ошибаюсь).

... или сделать то же самое с помощью встроенной оболочки read, которая по неизвестным мне причинам обрабатывает всю строку даты как одно слово (четвертое слово в выходной строке, где read помечает первые четыре слова именами 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

Наконец, возможно, стоит превратить его в метку времени в секундах с начала эпохи для удобства сравнения:

._. printedDatestamp=$(date --date="$printJobDateString" +%s)
._. echo $printedDatestamp
1618741256

printJobDateString будет пустым, если lpstat не имел записи о задании в своем завершенном списке. В этом случае date будет считать, что это 1/1/1970, когда вы преобразуете его в секунды эпохи.

Хотя на самом деле, то весьма маловероятно, что ваше задание печати не попадет в список «завершенных» заданий, поскольку в этом списке, по-видимому, содержатся как отмененные, так и завершенные задания.Поэтому игнорируйте предупреждение ниже.. Ха.

Но будьте осторожны, если lpstat не имеет вашего задания печати, он вернет пустую строку. А если вы скармливаете 'date' пустую строку, он выдаст сегодняшнюю дату. И если у вас есть это в скрипте, это может ввести вас в заблуждение, заставив думать, что задание выполнено, потому что он вернет вам сегодняшнюю дату.

Например:

._. date -d @$(date --date="" +%s) +"%F %T %z"
2021-04-17 00:00:00 +0100

В то время как «date» принимает 0 как начало «эпохи» Unix (рассвет крутого времени) - 1 января 1970 г.:

._. date -d @0 +"%F %T %z"
1970-01-01 01:00:00 +0100

Это может быть более полезным указанием на невыполненную работу, чем сегодняшняя дата. Поэтому преобразуйте пустую строку в ноль (если он у вас есть) перед тем, как скармливать ее 'date', возможно, так:

._. emptyString=""
._. zero=$( [[ -z "$emptyString" ]] && echo 0 || echo "$emptyString" )
._. echo zero
0

Другими словами, сгенерируйте метку даты следующим образом:

._. printedDatestamp=$(date --date="$( [[ -z "$printJobDateString" ]] && echo 0 || echo "$printJobDateString" )" +%s)

Наконец, все шаги вместе:

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

ПС

Используйте sleepтакже после отправки задания на печать в цикле, который продолжается до тех пор, пока не получите пустую строку, выполняя grep-проверку вашего printJob по выходным данным lpstat -W "not-completed". Только затем опрашивайте lpstat -W "completed".

Вот: временная метка задания печати. ​​И кто сказал, что управление печатью в Linux гуманно? Никто. Никто ничего подобного не говорил. И все, что они говорили об этом, они бормотали себе под нос.

Связанный контент