CUPS 印刷ジョブのタイムスタンプを表示する

CUPS 印刷ジョブのタイムスタンプを表示する

CUPS でジョブのタイムスタンプを表示する方法を探しています。マニュアル ページを検索しましたが、見つからないようです。

長期的な目標は、ジョブ ID から時間を解析し、一定期間を過ぎたジョブを自動的に削除してサーバーの過負荷を回避するスクリプトを作成することです。私の CUPS サーバーには 2000 を超える印刷キューがあります。

答え1

U&L サイト内で、これを行うためのヒントを与えてくれそうな次の 2 つの質問を見つけました。これら 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

したがって、これを実行する 1 つのハック的な方法は、システム上のユーザーのリストを形式化し、それを-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

問題?

これに関する 1 つの問題は、CUPS に印刷するユーザーがローカルにアカウントを持っていない場合、そのアカウントが表示されないことです。

ただし、LPD 制御ファイルを含むディレクトリがある場合、通常は /var/spool/cups , you'll notice a bunch of control files in there. These files are kept as a result of theMaxJobs 設定であり、設定されていない場合はデフォルトで 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

古い印刷ジョブをクリーンアップするための、おそらくもっと簡単な方法がもう 1 つあります。印刷ジョブの短縮されたタイム スタンプを変換する方法を見つける代わりに、特定の条件に一致する古い印刷ジョブを削除するタスクを実行するには、find コマンドを使用する方が簡単です。たとえば、4 日以上前の印刷ジョブを検索する場合は、次のようにします。

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

/var/spool/cupscups 内のすべてのアクティブな印刷ジョブには、拡張子 のファイルがあります-001。その後は、お気に入りの文字列操作ツールを使用して、出力から実際の印刷ジョブ番号を取得するだけです。

答え3

実際には、これらすべてを完全に無視し、ジョブリストから日付を取得しようとする必要はありません。ただし、正確な印刷ジョブのタイムスタンプが必要な場合、lpstat の出力やマニュアルから、指定された日時がジョブが送信された日時なのか、完了した日時なのかはすぐにはわかりません。

「完了」ジョブ リストでジョブを検出した時点で「現在」の日付スタンプを生成できるため、これを実行する必要はまったくありません。

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

もちろん、ジョブが完了したかどうかは、完了するまでわかりません。そのため、完了したことを検出するまでループしてスリープ状態にしておくとよいでしょう。

キューにある日付が必要な場合は、次のようにします。

印刷指示を送信するときに、印刷ジョブ ID を取得します。

._. 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}'出力文字列の 4 番目の単語を取得します)。

次に、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。理由はわかりませんが、これは日付文字列全体を 1 つの単語として扱います (出力文字列の 4 番目の単語。read は最初の 4 つの単語を 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

lpstat の完了リストにジョブの記録がない場合、printJobDateString は空になります。その場合、date はそれをエポック秒に変換すると 1/1/1970 であると想定します。

実はただし、印刷ジョブが「完了」ジョブ リストに含まれない可能性は非常に低いと考えられます。このリストには、完了したジョブだけでなくキャンセルされたジョブも収集される可能性があるためです。以下の警告は無視してくださいはあ。

ただし注意してくださいlpstat に印刷ジョブがない場合、空の文字列が返されます。また、「date」に空の文字列を入力すると、今日の日付が出力されます。スクリプトにこれが含まれていると、今日の日付が表示されるため、ジョブが完了したと誤解する可能性があります。

例えば:

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

一方、「date」は0をUnixの「エポック」の開始としてとらえます(グルーヴィーな時間の始まり) - 1970年1月1日:

._. 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印刷ジョブを送信した後、 の出力に対して printJob を grep して、空の文字列が取得されるまでループを続ける も使用しますlpstat -W "not-completed"。その後でのみ をポーリングしますlpstat -W "completed"

印刷ジョブのタイムスタンプがあります。Linux の印刷制御が人道的だと言ったのは誰ですか? 誰もいません。誰もそんなことは言っていません。そして、それについて言ったことはすべて、小声でつぶやくだけでした。

関連情報