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 |
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.
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.
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.
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.
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.
sudo firewall-cmd --zone=public --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 |
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.)