我想告诉我的 cups 打印服务器保留所有打印作业,直到它们被手动释放。
使用cupsdisable --hold <printer or class>
会暂停打印机,并且lpoptions -p <printer> -o hold-job-until=indefinite
适用于本地提交的打印作业,但不适用于远程发送的作业。如何配置杯子以保留所有作业,直到手动释放它们为止?
答案1
我没有找到杯子的配置选项,该选项确实将每个传入的打印作业设置为暂停。我编写了一个 bash 脚本来完成这项工作:
#!/bin/bash
# cups_hold_new_jobs [<printer>]
# Resume a cups printer, set all queued and newly incoming jobs on
# hold, pause printer and exit.
# Runs as long as there are jobs in the print queue. Start from cron.
DEBUG=false
# --------- do not edit below ---------
VERSION=0.3
VERSION_INFO="(c) 2024 by Adrian Zaugg under GNU General Public License Version 3."
# initiate job list
declare -a JOBS
# set defaults
LOCK="/run/$(basename "$0")"
LOCKED=false
OWNPIDPPID="$$ $PPID "
# get job list
function get_job_list() {
JOBS=($(lpstat -o "$PRINTER" | sed -e 's/^\('"$PRINTER"'-[0-9]\+\).*$/\1/g'))
}
# DEBUG variable must be set to true or false
if [[ "$DEBUG" != "true" && "$DEBUG" != "false" ]]; then
DEBUG=false
fi
# cups must be running
if [ $(lpstat -r | grep -c "is running") -eq 0 ]; then
$DEBUG && echo "[INFO] CUPS is not running. Nothing to do." >&2
exit 0
fi
# get printer (or class?)
PRINTER="$1"
# get default printer if none was given as an argument or check given printer name
if [ -z "$PRINTER" ]; then
PRINTER="$(lpstat -p -d 2>/dev/null | grep "^system default destination: " | sed -e 's/^system default destination: //')"
# check
if [ -z "$PRINTER" ]; then
echo "[ERROR] No printer given on command line and unable to detect default printer." >&2
exit 1
else
$DEBUG && echo "No printer given on command line, using default printer: $PRINTER" >&2
fi
else
# no space, hash, slash or newline in printer names allowed
PRINTER="$(echo "$PRINTER" | head -1 | sed -e "s%/.*$%%" -e "s/#.*$//" -e "s/ .*$//")"
if [ ${#PRINTER} -lt ${#1} ]; then
echo "[ERROR] Disallowed characters in printer name found."
exit 1
fi
# check given printer exists
ERR="$(lpstat -p "$PRINTER" 2>&1)"
if [ $? -ne 0 ]; then
# printer does not exist or other error
echo "[ERROR] No printer printer \"$PRINTER\" found." >&2
exit 1
else
$DEBUG && echo "Using printer: $PRINTER" >&2
fi
fi
# lock
while ! $LOCKED; do
mkdir "$LOCK" 2>/dev/null
if [ $? -eq 0 ]; then
LOCKED=true
break;
elif [ $(ps -e -o pid,ppid,command | sed -n "s/\([0-9]\{1,\}\)[^0-9]\{1,\}\([0-9]\{1,\}\)[^0-9]\(.*\)$/\1\t\2\t\3/p" | \
grep -v "$OWNPIDPPID" | grep -cE 'bash .*/'"$(basename "${0}")"'$') -gt 1 ]; then
# process already started
$DEBUG && echo "Another instance of this script is already running." >&2
exit 0
else
# stale lock, remove it
rmdir "$LOCK" 2>/dev/null
if [ $? -ne 0 ]; then
echo "[ERROR] Removing stale lock $LOCK failed." >&2
exit 1
else
$DEBUG && echo "Removed stale lock." >&2
fi
fi
done
# pause printer
if [ $(lpstat -p "$PRINTER" | grep -c -m 1 "$PRINTER disabled") -eq 0 ]; then
cupsdisable "$PRINTER"
$DEBUG && echo "Printer paused." >&2
fi
PRINTER_PAUSED=true
# loop as long as there are jobs in the queue
get_job_list
until [ ${#JOBS[@]} -eq 0 ]; do
# find index of last held job in new job list
last_held_job_index=0
unset job_id
while [[ "${JOBS[$last_held_job_index]}" != "$last_held_job_id" && $last_held_job_index -le ${#JOBS[@]} ]]; do
last_held_job_index=$(($last_held_job_index+1))
done
if [ $last_held_job_index -eq ${#JOBS[@]} ]; then
# job not found
last_held_job_index=-1
fi
# set newly queued jobs on hold
i=0
for job_id in ${JOBS[@]}; do
# compare index to marker of last held index
if [ $i -gt $last_held_job_index ]; then
# set job on hold
ERR="$(lp -i "$job_id" -H hold 2>&1)"
if [ $? -eq 0 ]; then
echo -e "[INFO] holding job $job_id" >&2
else
echo "[ERROR] Failed to hold job \"$job_id\": $ERR" >&2
fi
# remember last index
last_held_job_index=$i
fi
i=$(($i+1))
done
last_held_job_id="${JOBS[$last_held_job_index]}"
# wait a bit
sleep 1
# reread jobs in print queue
get_job_list
# enable printer now
if $PRINTER_PAUSED; then
cupsenable "$PRINTER"
PRINTER_PAUSED=false
fi
done
# queue is now empty disable printer
if $PRINTER_PAUSED; then
$DEBUG && echo "Queue is empty." >&2
else
cupsdisable "$PRINTER"
echo "[INFO] Queue is empty now, pausing printer $PRINTER." >&2
fi
# unlock
if $LOCKED; then rmdir "$LOCK"; fi
exit 0
该脚本在启动时暂停打印机,将所有现有作业设置为暂停,对新传入的作业执行相同的操作,取消暂停打印机并等待队列变空。退出后,它会再次暂停打印机。
这个想法是,打印作业可以由其所有者手动释放或取消(或通过杯子设置 MaxHoldTime 自动取消)。这是简单拉式打印系统的一部分。
这是脚本的第一个版本,它在竞争条件下受到影响,必须由 cron 调用,缺少帮助文本,未针对类、asf 进行测试。如果我添加功能或修复,我会发布下载链接在这个答案中。使用它由您自己负责。不要在生产中使用,它在这里给出一个如何完成的想法。
很高兴听到有一种更简单的方法来告诉 cups 暂停所有传入的作业无需大量额外软件即可构建跟随我的打印系统。
下载:复制上述内容失败,因为选项卡可能会丢失,请使用下载链接:https://ente.limmat.ch/ftp/pub/software/bash/cups/