Scanning and Printing From CLI

I recently purchased a Brother MFC-L3780CDW color laser printer/scanner. (It also does copies and faxes, though I don't have a landline.) I saw that they had Linux drivers for it on their site, and some startpaging made me think I could easily get it working with FreeBSD which is what I run on my main workstation. (Spoiler Alert: It worked.)

As this was my new toy, and I had little scanning or printing to do, I wound up installing a few bhyve VM's using vm-bhyve, and while I found it was pretty easy to get both scanning and printing working without the drivers from the Brother website, it seemed that various systems had little quirks, making it a little more difficult than I'd expected.

I did this page mainly to give myself a place to look if I have to set up a printer or scanner on any of these systems. All of the systems mentioned were tested on FreeBSD vm-bhyve virtual machines, including a minimal non-gui install of FreeBSD itself.

So here you have my way of printing or scanning, without a GUI, on FreeBSD, OpenBSD, and several versions of Linux.

For this article, we'll call the printer BrotherMFC at the IP of 192.168.1.50 on the LAN.

If all you're doing is printing pdf files, you don't even need cups to print. You can use, on any of the systems below, netcat, with the command
nc 192.168.1.50 9100 < myfile.pdf

However,with the lp and lpadmin commands, one can do a lot more, such as set paper size, use duplex printing, etc. So, we'll cover installing cups and using its lp and lpadmin commands. We won't cover its many options--interested readers can do a web search for one of the many lpadmin tutorials--but we will cover getting it installed and setting up the printer.

One caveat is that it won't print libreoffice files unless they're exported to pdfs. As I only need to print pdfs, I've never looked too deeply into this, but if you have libreoffice on the machine, you can print with
libreoffice -p BrotherMFC <document-name>

Or use the libreoffice convert option.
libreoffice --convert-to pdf myfile.docx 

Table of Contents (TOC)

FreeBSD
OpenBSD
AlpineLinux
ArchLinux
Fedora
RedHat and Clones
VoidLinux

FreeBSD

For FreeBSD, one has to install dbus and sane-airscan with pkg install. Although sane-airscan has a package message about running avahi, I didn't have to do anything but start dbus with service dbus start. After that, scanimage -L found the scanner with no problem.

Netcat will print pdfs without any problem, whether it's grayscale or color.

However, you may need some of lp's options. So use pkg install to install cups and cups-filters. To set up the printer, making it the default, one uses the -d option. You need root or root privilege, we'll use sudo in the example.
sudo pkg install cups cups-filters
sudo service cupsd start
sudo lpadmin -p BrotherMFC -E -v ipp://192.168.1.50/ipp/print -m everywhere
sudo lp -d BrotherMFC

The -p is the device name, you can call it whatever you want. -E is to enable it, -v is for the device and -m for the ppd file. As the man page will tell you if if you specify -E *before* the -p (or -d or -x) options, it will force encryption, but where we have it in the command it just enables the printer.

As the lp command is a FreeBSD builtin, in /usr/bin, which would be the default, rather than running lp myfile, you have to run /usr/local/bin/lp myfile.pdf. If you print from the web interface, or, say, from Firefox, you won't run into this. However from CLI if you just put lp it will look for /usr/bin/lp and won't print. For my own personal use, I almost always use netcat because in the last couple of years, all I've had to print were pdfs, so I haven't fixed this. but there are various recommendations

I have an ancient page that covers just renaming /usr/bin/lp and symlinking it to /usr/local/bin/lp. Other things mentioned there are from back when I would install cups using ports and had suggestions for the Makefile. I've also seen a suggestion to edit your PATH variable so that /usr/local/bin comes before /usr/bin. If the reader wants to use lp on FreeBSD, they can decide for themselves the way they'd prefer to do it.

TOC

OpenBSD

For OpenBSD, I'll mention, that it might be worth seeing my vm-bhyve page. There's a newer OpenBSD template that uses uefi, but it has a couple of gotchas.

Anyway, to get scanning and cups working in OpenBSD, run pkg_add to install dbus, avahi, and sane-backends. When you run pkg_add sane-backends, it gives you several choices. Choose escl. You can use sudo, but many OpenBSD users prefer doas.
doas pkg_add dbus avahi sane-backends
doas rcctl enable messagebus avahi_daemon 
doas rcctl start messagebus avahi_daeman

After that scanimage -L will show the scanner.

If you're only going to want these running when you're using the scanner, rather than rcctl enable, you can use rcctl -f start. The -f is for force, and used to start a service that isn't enabled. To get printing it's simply a matter of pkg_add cups and then starting cups with rcctl enable cupsd, and then run rcctl start cupsd. Again, if you only want it to run at times, you can use rcctl -f start cupsd. (Running pkg_add cups already installed cups-filters. you can check with pkg_info |grep cups).
doas pkg_add cups
doas rcctl enable cupsd
doas rcctl start cupsd
lpadmin -p BrotherMFC -E -v ipp://192.168.1.50/ipp/print -m everywhere
lpadmin -d BrotherMFC

You don't need doas to set up the printer for your user.

If you now run lp default-testpage.pdf, you don't need to specify that it's /usr/local/bin/lp. Usually, the testpage is included with cups, on the BSD's and most of the Linux versions I mention here. On the BSDs it's in /usr/local/share/cups/data/default-testpage.pdf, on Linux it'll be /usr/share/cups/data/default-testpage.pdf.

TOC

AlpineLinux

Alpine has airscan in its testing repository, but you don't need it to scan, at least with my Brother MFC. You will need to uncomment the line for the community packages in /etc/apk/repositories. Alpine also uses doas though I believe sudo's available.
doas apk add sane-backends avahi
doas service avahi-daemon start

scanimage -L should now find the scanner.

For printing
doas apk add cups cups-filters
doas service cupsd start

Then the same lpadmin command we've used with the BSDs. It's the same command with all of these systems.
doas lpadmin -p BrotherMFC -E -v ipp://192.168.1.50/ipp/print -m everywhere
doas lpadmin -d BrotherMFC

You can then run lp default-testpage.pdf. I don't remember if Alpine had the page included in the cups install. Most of these systems had it, but some didn't. You can test with any file though. Alpine, like all the others, will also print pdfs with nc 192.168.1.50 9100 < myfile.

TOC

ArchLinux

Using the Brother with ArchLinux is pretty simple.
sudo pacman -S sane-airscan cups
sudo systemctl start cups
sudo lpadmin -p BrotherMFC -E -v ipp://192.168.1.50/ipp/print -m everywhere
sudo lpadmin -d BrotherMFC

(sane gets pulled in by sane-airscan).

Once sane and airscan are installed, running scanimage -L should show that the scanner is recognized. If you want cups to always run, rather than just this once
systemctl enable --now cups

Which will enable it after reboot as well as start the service now.

TOC

Fedora

For this Fedora VM, I chose minimal install. As with Arch, it was pretty simple to get things working.
sudo dnf install avahi sane-backends cups cups-filters
sudo systemctl start avahi-daemon cups 
sudo lpadmin -p BrotherMFC -E -v ipp://192.168.1.50/ipp/print -m everywhere
sudo lpadmin -d BrotherMFC

Running scanimage -L saw the scanner and running lp /usr/share/cups/data/default-testpage.pdf printed the page.

For this to work on subsquent boots the correct way
sudo systemctl --now enable avahi-daemon   cups

As with Arch above, this will start the two daemons and enable them with every boot.

TOC

RedHat and Similar (Rocky, Alma)

With Redhat I chose the default install, so cups and avahi were already installed and running. However, it didn't see the scanner until I let mdns (multicast DNS) through on the firewall.
sudo firewall-cmd --zone=public --add-service mdns --permanent

On another RedHat install, where the connection was wireless, rather than wired, I had to use "home" as the zone.
sudo firewall-cmd --zone=home --add-service mdns --permanent

To set up CLI printing I used the command we've used with the previously mentioned systems.
sudo lpadmin -p BrotherMFC -E -v ipp://192.168.1.50/ipp/print -m everywhere
sudo lpadmin -d BrotherMFC

TOC

VoidLinux

I had little trouble getting the machine working with Void.
sudo xbps-install -Sy sane sane-airscan cups cups-filters
sudo ln -s /etc/sv/cupsd /var/service
sudo sv up cupsd
sudo lpadmin -p BrotherMFC -E -v ipp://192.168.1.50/ipp/print -m everywhere
sudo lpadmin -d BrotherMFC

After that running lp would print and scanimage -L found the scanner.

As I said at the beginning this is mostly for myself, to remind myself in case I have to set up a printer/scanner again. While these instructions are for a Brother, as both airscan and ipp seem machine independent, they should work with most printer/scanners on the market.

If one has several pages to scan (this should be true on all, or almost all, of the systems mentioned), one can use scanimage with the --batch option. Use the ADF (automatic document feeder), and, for example
#!/bin/sh
scanimage --source adf --mode Color --format pdf --batch &&
pdftk out1.pdf burst

If I've set the format to pdf, it produces a single file, containing all the pdfs, called out1.pdf. There are various programs to put them into separate files, I use pdftk. So the line of pdftk out1.pdf burst will separate out1.pdf into a separate pdf for each page, called pg_0001.pdf, pg_0002.pdf and so on. (You can choose other names, see man(1) pdftk.)