Ich suche nach einer Möglichkeit, den Zeitstempel eines Jobs in CUPS anzuzeigen. Ich habe die Manpages durchsucht und kann sie scheinbar nicht finden.
Das langfristige Ziel ist ein Skript, das die Zeit anhand der Job-ID analysiert und automatisch alle Jobs löscht, die älter als ein bestimmtes Alter sind, um eine Überlastung des Servers zu vermeiden. Mein CUPS-Server hat über 2000 Druckwarteschlangen.
Antwort1
Ich habe auf der U&L-Site die folgenden beiden Fragen gefunden, die Hinweise zu einer möglichen Vorgehensweise zu geben scheinen. Diese beiden Fragen:
- Alle Druckaufträge des Benutzers über die Befehlszeile anzeigen
- Wie wird der Verlauf der CUPS-Druckeraufträge angezeigt?
Scheint zu bedeuten, dass Sie verwenden könnten, lpstat
um das zu bekommen, was Sie wollen. Mir ist aufgefallen, dass ich diesen Befehl ausführen könnte:
$ sudo lpstat -W completed
mfc-8480dn-1652 root 1024 Tue 28 Jan 2014 01:19:34 AM EST
Und das hier:
$ 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
Aber es -u all
hat bei mir nichts bewirkt.
$ sudo lpstat -W completed -u all | head -2
$
Kurioserweise konnte ich Folgendes tun:
$ 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
Eine Möglichkeit hierfür wäre, eine Liste der Benutzer Ihres Systems zu formalisieren und diese dann als Unterbefehl zum -u
Argument hinzuzufügen, und zwar wie folgt:
$ sudo lpstat -W completed -u $(getent passwd | \
awk -F: '{print $1}' | paste -sd ',')
Um zu zeigen, dass alle Benutzer lokal angezeigt werden, können Sie wie folgt eine eindeutige Liste Ihrer Benutzer abrufen:
$ sudo lpstat -W completed -u $(getent passwd | \
awk -F: '{print $1}' | paste -sd ',') | awk '{print $2}' | sort -u
ethan
root
sam
tammy
Probleme?
Ein Problem dabei besteht darin, dass der Benutzer, der über CUPS druckt, nicht angezeigt wird, wenn er nicht über ein lokales Konto verfügt.
Wenn Sie jedoch über ein Verzeichnis verfügen, das Ihre LPD-Steuerdateien enthält, handelt es sich normalerweise um , you'll notice a bunch of control files in there. These files are kept as a result of the
die MaxJobs-Einstellung in /var/spool/cups, die standardmäßig auf 500 gesetzt ist, wenn sie nicht festgelegt ist.
$ sudo ls -l /var/spool/cups/ | wc -l
502
Eine andere Quelle für Benutzernamen?
Wenn Sie diese Dateien durchsehen, werden Sie feststellen, dass sie Benutzernamen enthalten und nicht nur solche für im System vorhandene Konten.
$ strings /var/spool/cups/* | grep -A 1 job-originating-user-name | head -5
job-originating-user-name
tammyB
--
job-originating-user-name
tammyB
Wir könnten also alle Einträge auswählen, die den Benutzernamen gefolgt vom B enthalten.
$ 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
Diese Liste kann dann auf die gleiche Weise angepasst werden, wie wir sie ursprünglich verwendet haben, um die Liste der Benutzer von zu übernehmen getent passwd
, und zwar wie folgt:
$ 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
Verweise
Antwort2
Ich habe einen anderen, vielleicht einfacheren Ansatz zum Bereinigen alter Druckaufträge. Anstatt einen Weg zu finden, die verkürzten Zeitstempel der Druckaufträge zu konvertieren, ist es einfacher, den Befehl „find“ zu verwenden, um alte Druckaufträge zu löschen, die einem bestimmten Kriterium entsprechen. Wenn Sie beispielsweise Druckaufträge finden möchten, die älter als 4 Tage sind:
find /var/spool/cups -name "*-001" -mtime +4
Alle aktiven Druckaufträge in CUPS haben Dateien /var/spool/cups
mit der Erweiterung -001
. Danach müssen Sie nur noch Ihr bevorzugtes Tool zur String-Manipulation verwenden, um die tatsächliche Druckauftragsnummer aus der Ausgabe abzurufen.
Antwort3
Ignorieren Sie das alles wirklich und versuchen Sie erst gar nicht, das Datum aus der Jobliste zu bekommen. Sie müssen nicht,es sei denn, Sie benötigen einen punktgenauen Zeitstempel für den Druckauftrag (und selbst dann ist aus der Ausgabe oder dem Handbuch von lpstat nicht sofort ersichtlich, ob die angegebene Datums- und Uhrzeitangabe sich auf den Zeitpunkt bezieht, zu dem der Auftrag gesendet oder abgeschlossen wurde).
Sie müssen dies überhaupt nicht tun, da Sie einfach einen Datumsstempel „jetzt“ generieren können, sobald Sie Ihren Auftrag in der Liste der „abgeschlossenen“ Aufträge erkennen.
._. printJob=$(lp somefile | awk '{print $4}')
._. printJobCompleted=$(lpstat -W "completed" | grep $printJob )
._. printedDatestamp=$(date +%s)
Allerdings können Sie natürlich erst dann feststellen, dass der Auftrag abgeschlossen ist. Sie sollten also eine Schleife ausführen und in den Ruhezustand wechseln, bis Sie feststellen, dass dies der Fall ist.
Wenn Sie das Datum haben möchten, das in der Warteschlange steht, gehen Sie vielleicht so vor:
Erfassen Sie Ihre Druckauftrags-ID, wenn Sie die Druckanweisung senden:
._. printJob=$(lp somefile | awk '{print $4}')
._. echo $printJob
Kyocera-ECOSYS-P5021cdw-564
(Es ist notwendig, die Ausgabe von lp durch awk zu analysieren, da lp anscheinend keine Möglichkeit hat, den Druckauftrag einfach zurückzugeben):
._. lp somefile
request id is Kyocera-ECOSYS-P5021cdw-568 (1 file(s))
( awk '{print $4}'
holt das vierte Wort dieser Ausgabezeichenfolge).
Verwenden Sie dann lpstat, um die Details des abgeschlossenen Auftrags abzurufen:
._. lpstat -W "completed" | grep $printJob
Kyocera-ECOSYS-P5021cdw-564 ming 2048 Sun 18 Apr 2021 11:20:56 BST
Das Isolieren des Teils, der das Datum enthält, ist etwas umständlich, da lpstat keine direkte Möglichkeit dafür zu bieten scheint und das Datum aus mehreren Wörtern besteht. Also vielleicht entweder:
._. printJobDateString=$(lpstat -W "completed" | grep $printJob | awk '{print $4,$5,$6,$7,$8,$9}')
._. echo $printJobDateString
Sun 18 Apr 2021 11:20:56 BST
(Und awk scheint auch keine Möglichkeit zum Erfassen eines Bereichs zu bieten – korrigieren Sie mich bitte, wenn ich falsch liege).
... oder machen Sie dasselbe mit dem in der Shell integrierten read
, das aus mir unbekannten Gründen die gesamte Datumszeichenfolge als ein einzelnes Wort behandelt (das vierte Wort in der Ausgabezeichenfolge, wobei read die ersten vier Wörter mit den Namen a, b, c, d markiert):
._. 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
Zum Schluss können Sie es zum einfacheren Vergleich vielleicht in einen Datumsstempel mit den Sekunden seit der Epoche umwandeln:
._. printedDatestamp=$(date --date="$printJobDateString" +%s)
._. echo $printedDatestamp
1618741256
printJobDateString ist leer, wenn lpstat keinen Eintrag des Auftrags in seiner Liste der abgeschlossenen Aufträge hat. In diesem Fall wird date beim Umrechnen in Epochensekunden als 1.1.1970 angenommen.
Eigentlich aber, ist es möglicherweise sehr unwahrscheinlich, dass Ihr Druckauftrag nicht in der Liste der „abgeschlossenen“ Aufträge landet, da diese Liste sowohl stornierte als auch abgeschlossene Aufträge zu sammeln scheint.Ignorieren Sie daher die Warnung unten... Ha.
Aber Vorsicht, wenn lpstat Ihren Druckauftrag nicht hat, gibt es eine leere Zeichenfolge zurück. Und wenn Sie „date“ eine leere Zeichenfolge zuführen, wird das heutige Datum ausgegeben. Und wenn Sie das in einem Skript haben, könnte es Sie fälschlicherweise glauben lassen, der Auftrag sei abgeschlossen, weil es Ihnen das heutige Datum gibt.
Zum Beispiel:
._. date -d @$(date --date="" +%s) +"%F %T %z"
2021-04-17 00:00:00 +0100
Während für 'date' der Wert 0 als Beginn der Unix-'Epoche' angenommen wird (der Beginn einer groovigen Zeit) - 1. Januar 1970:
._. date -d @0 +"%F %T %z"
1970-01-01 01:00:00 +0100
Dies könnte sinnvoller sein, einen nicht abgeschlossenen Auftrag anzuzeigen, als das heutige Datum. Wandeln Sie also die leere Zeichenfolge in eine Null um (falls Sie eine erhalten), bevor Sie sie an „date“ weiterleiten, etwa so:
._. emptyString=""
._. zero=$( [[ -z "$emptyString" ]] && echo 0 || echo "$emptyString" )
._. echo zero
0
Mit anderen Worten: Generieren Sie den Datumsstempel folgendermaßen:
._. printedDatestamp=$(date --date="$( [[ -z "$printJobDateString" ]] && echo 0 || echo "$printJobDateString" )" +%s)
Zum Schluss alle Schritte noch einmal zusammengefasst:
._. 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
Verwenden Sie es sleep
auch, nachdem Sie den Druckauftrag gesendet haben, in einer Schleife, die so lange läuft, bis Sie eine leere Zeichenfolge erhalten, indem Sie Ihren Druckauftrag über die Ausgabe von greppen lpstat -W "not-completed"
. Erst dann pollen Sie lpstat -W "completed"
.
Da: der Zeitstempel eines Druckauftrags. Und wer hat gesagt, dass die Linux-Drucksteuerung human sei? Niemand. Niemand hat so etwas gesagt. Und alles, was sie darüber sagten, murmelten sie vor sich hin.