Skip to content
This repository was archived by the owner on May 11, 2024. It is now read-only.

Updated guide to use cupsctl #251

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 11 additions & 21 deletions how-to-disable-cups-printer-job-history-on-macos/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Title: How to disable CUPS printer job history on macOS
Description: Learn how to disable CUPS printer job history on macOS.
Author: Sun Knudsen <https://github.com/sunknudsen>
Contributors: Sun Knudsen <https://github.com/sunknudsen>
Contributors: Sun Knudsen <https://github.com/sunknudsen>, Carl P. Corliss <https://github.com/rabbitt>
Reviewers:
Publication date: 2022-10-29T13:05:18.112Z
Listed: true
Expand Down Expand Up @@ -33,23 +33,19 @@ sudo mkdir -p /usr/local/sbin
sudo chown ${USER}:admin /usr/local/sbin
```

### Step 3: create `cups.sh` script
### Step 3: create `cups.sh` script (see CUPS [docs](https://www.cups.org/doc/man-cupsd.conf.html))

```shell
cat << "EOF" > /usr/local/sbin/cups.sh
#! /bin/sh

set -e

if grep -qe '^PreserveJobHistory Off$' /etc/cups/cupsd.conf; then
if cupsctl | grep PreserveJobHistory=no > /dev/null 2>&1; then
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use grep -q here to silence the output from grep, and rely on the status code returned depending on whether the search term was found or not, and avoid having to redirect stdout/stderr, e.g.:

# ensure idempotent operation - exit if change already exists
if cupsctl | grep -iqE 'PreserveJobHistory\s*=\s*no'; then

Also, if you wanted, you could also simplify that down to a single line:

# ensure idempotent operation - exit if change already exists
cupsctl | grep -iqE 'PreserveJobHistory\s*=\s*no' && exit 0

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using grep’s --quiet flag is much cleaner, thanks!

Elegant one-liner… that said, if and then might be more literal for people getting started with command line (I try to use long form when possible in guides hence using --quiet vs -q flag.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is regular expression necessary given config is generated programatically by cupsctl?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is regular expression necessary given config is generated programatically by cupsctl?

Probably not, I'm just paranoid 😳 lol

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, love how thorough you are. 🤓

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does lpstat -W completed -o purge job files from /var/spool/cups? Btw, not too worried about using cancel -a -x in this specific use case, but definitively worth considering.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does lpstat -W completed -o purge job files from /var/spool/cups?

It does, and it does it according to your settings (e.g., "PreserveJobXXX" and MaxJobTime). Also, with the -W completed flag, it only cleans up completed jobs, and not active jobs.

Btw, not too worried about using cancel -a -x in this specific use case, but definitively worth considering.

Sure, I'm just thinking that people tend to blindly run commands without researching them, so I figure using lpstat is safer as it doesn't kill jobs that are actively printing or stuck, only jobs that have actually completed. Maybe include both commands and explain the difference between the two (i.e., cancel blindly purges everything, vs lpstat -W completed -o just purges completed jobs).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for feedback… would you happen to have ideas to limit cupsctl calls while preserving command intelligibility for people who are just getting started (ideally, one command to get current state and one to update config if need be)?

My (perhaps naive) understanding is that, if above is implemented, config would be updated 3 times which would also reload CUPS same amount of times.

Copy link
Author

@rabbitt rabbitt Nov 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a more thorough rewrite that is idempotent, logs changes to syslog, and only calls out to cupsctl at most once:

#!/bin/bash

set -e

function log() {
    # If no arguments, return immediately
    [[ $# -le 0 ]] && return 
    echo "$@"
    /usr/bin/syslog -s -l info "cups-privacy: $@" 
}

# store settings in bash variables so that, if we decide to change them,
# we only have to change the values in one place
PreserveJobHistory=no
PreserveJobFiles=no
MaxJobTime=5m

settings="$(/usr/sbin/cupsctl | /usr/bin/awk -f <(cat <<EOF
    BEGIN { pjh=pjf=mjt=1 } 
    /PreserveJobHistory=${PreserveJobHistory}/ { pjh=0 } 
    /PreserveJobFiles=${PreserveJobFiles}/ { pjf=0 } 
    /MaxJobTime=${MaxJobTime}/ { mjt=0 } 
    END { 
        if (pjh==1) { print("PreserveJobHistory=${PreserveJobHistory}") } 
        if (pjf==1) { print("PreserveJobFiles=${PreserveJobFiles}") } 
        if (mjt==1) { print("MaxJobTime=${MaxJobTime}") } 
    }
EOF
) | /usr/bin/xargs)"


# if nothing to change, exit 
if [[ -z $settings ]]; then
    log "Settings configured correctly; nothing to do."
    exit 0
fi

log "Updated missing or incorrect CUPS settings: ${settings}"
/usr/sbin/cupsctl $settings

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @sunknudsen - I'm sure you've been pretty busy, especially with holidays just past us. Wanted to follow up on this request and see if there's any thoughts on moving forward with the discussion and changes ?

exit 0
fi

echo "PreserveJobHistory Off" | sudo tee -a /etc/cups/cupsd.conf

sudo launchctl unload /System/Library/LaunchDaemons/org.cups.cupsd.plist

sudo launchctl load /System/Library/LaunchDaemons/org.cups.cupsd.plist
cupsctl MaxJobTime=5m PreserveJobFiles=no PreserveJobHistory=no
EOF
```

Expand All @@ -61,6 +57,8 @@ chmod +x /usr/local/sbin/cups.sh

### Step 5: create `local.cups.plist` launch daemon

> Heads-up: used to make sure user-defined config persists macOS updates.

```shell
cat << "EOF" | sudo tee /Library/LaunchDaemons/local.cups.plist
<?xml version="1.0" encoding="UTF-8"?>
Expand Down Expand Up @@ -90,32 +88,24 @@ EOF

## Want things back the way they were before following this guide? No problem!

### Step 1: delete `PreserveJobHistory Off` line from `cupsd.conf`

```shell
sudo sed -i "" "/PreserveJobHistory Off/d" /etc/cups/cupsd.conf
```

### Step 2: delete `cups.sh` script
### Step 1: delete `cups.sh` script

```shell
sudo rm /usr/local/sbin/cups.sh
```

### Step 3: delete `local.cups.plist` launch daemon
### Step 2: delete `local.cups.plist` launch daemon

```shell
sudo rm /Library/LaunchDaemons/local.cups.plist
```

### Step 4: reload CUPS
### Step 3: revert user-defined config to CUPS defaults

```shell
sudo launchctl unload /System/Library/LaunchDaemons/org.cups.cupsd.plist

sudo launchctl load /System/Library/LaunchDaemons/org.cups.cupsd.plist
cupsctl MaxJobTime= PreserveJobFiles= PreserveJobHistory=
```

### Step 5: reboot
### Step 4: reboot

👍