Perfect — let’s set this up entirely from the command line, no GUI or web interface. You’ll connect to a Windows shared printer (SMB) and register it in CUPS so you can use it with lp or lpr.


🧰 1. Install required tools

Install CUPS and Samba support for SMB printers:

Debian/Ubuntu:

sudo apt install cups smbclient

Arch / Manjaro:

sudo pacman -S cups samba

Fedora:

sudo dnf install cups samba-client

⚙️ 2. Start and enable CUPS

sudo systemctl enable --now cups

🔍 3. Check the shared printer on the Windows host

You can discover what printers are shared:

smbclient -L //WINDOWS_HOST_IP -U WINDOWS_USER

Example:

smbclient -L //192.168.1.100 -U Administrator

You should see something like:

Sharename       Type      Comment
---------       ----      -------
HP_LaserJet     Printer   Office printer

So the printer URI will be:

smb://192.168.1.100/HP_LaserJet

🖨️ 4. Add the printer to CUPS from the CLI

You’ll use lpadmin:

sudo lpadmin -p HP_LaserJet \
  -v smb://username:password@192.168.1.100/HP_LaserJet \
  -E \
  -m everywhere

Explanation:

  • -p HP_LaserJet → Printer name in CUPS
  • -v → Device URI (SMB path)
  • -E → Enable the printer and accept jobs
  • -m everywhere → Use IPP Everywhere or a generic PPD driver

📝 If you prefer to avoid storing a password in the URI, omit it:

sudo lpadmin -p HP_LaserJet -v smb://username@192.168.1.100/HP_LaserJet -E -m everywhere

CUPS will prompt for credentials when needed.

⚠️ Verified caveats (tested on a Windows 10 host with an HP PSC 1400 and a Brother HL-L1222):

  • Host-based / GDI printers (most cheap inkjets and lasers: HP PSC/DeskJet, Brother HL-L1xxx, etc.): -m everywhere (or pxlmono, or raw text) will not work — Windows shows the job as printed but the printer outputs nothing. Install the model-specific driver (Arch: hplip for HP, the official Brother driver from AUR for Brother) and pass the real PPD with -P instead of -m.
  • The Windows account must be a normal user with a password. The built-in Guest account cannot print (tested with and without a password and with full permissions on the printer: the spooler accepts the job and deletes it immediately). Omitting the password in the URI only works if the user actually has one configured.
  • On host-based HP printers, also disable bidirectional support (BIDI) on the Windows side (printer Properties → port/advanced, or clear the 0x800 bit in the printer’s Attributes registry value) — otherwise Windows reads a false “empty ink cartridge” state and halts the job.

Full verified guide (Spanish): print_from_archlinux_to_windows.md.


✅ 5. Verify the printer

lpstat -p
lpstat -d

You should see your new printer listed and enabled.


🧪 6. Print a test file

For example:

echo "Test page from Linux" | lp -d HP_LaserJet

Or print a file:

lp -d HP_LaserJet /etc/hosts

🔒 7. (Optional) Store credentials

If Windows requires authentication and you want to avoid prompts, you can store credentials in the Samba config:

Edit /etc/samba/smb.conf and add:

[global]
   client min protocol = SMB2
   client max protocol = SMB3
   client plaintext auth = no
   name resolve order = bcast host
   workgroup = WORKGROUP

Then store credentials in:

~/.smbcredentials
username=your_windows_username
password=your_password

Set permissions:

chmod 600 ~/.smbcredentials

And use:

sudo lpadmin -p HP_LaserJet -v smb://:@192.168.1.100/HP_LaserJet -E -m everywhere

CUPS will automatically pick up your stored credentials via Samba.


🧰 Bonus: Default printer

If you want to make it your default printer:

lpoptions -d HP_LaserJet

Would you like me to show how to print with authentication automatically using Kerberos or domain credentials (useful for office networks)?