使用这个简单的 Bash 脚本在家中打印双面文档

使用这个脚本,免去手动加载和打印双面文档的麻烦和纸张浪费。
74 位读者喜欢这篇文章。
bash logo on green background

Opensource.com

我们家有一台激光打印机。这台惠普 LaserJet Pro CP1525nw 彩色打印机型号较旧,但一直是一款出色的主力机型,打印可靠且色彩鲜艳。几年前,我使用我们的 Raspberry Pi 作为打印服务器将其放入了我们的家庭网络

LaserJet 一直是我家庭办公室的得力助手。自从去年我创立了自己的公司以来,我一直依靠这台小型激光打印机为客户会议、研讨会和培训课程打印讲义和其他材料。

我对这台打印机唯一的抱怨是它只能单面打印。如果您想双面打印,您需要设置自定义打印作业才能自己完成。这很不方便,并且需要手动步骤。在 LibreOffice 中,我需要专门设置打印作业,先打印奇数页,然后再重新装纸,然后在另一面打印偶数页——但顺序相反。

LibreOffice print dialog

如果我需要打印别人发给我的 PDF 文件,过程也是一样的。对于四页文档,我首先需要打印第 1 页和第 3 页,然后重新装纸并以相反的顺序打印第 2 页和第 4 页。在 GNOME 打印对话框中,您需要选择“页面设置”才能打印奇数页或偶数页。

Gnome print dialog

Gnome page setup

无论我如何打印,整个过程都是打印奇数页,将打印好的页面堆叠重新装入纸盒,然后以相反的顺序打印偶数页。如果我要打印四页文档,以相反的顺序打印偶数页意味着第 4 页打印在第 3 页的背面,第 2 页打印在第 1 页的背面。想象一下,当我忘记选择以相反的顺序打印偶数页的选项并毁掉了一个冗长的打印作业时,我有多么沮丧。

同样,也很容易忘记如何处理页数是奇数的文档。在五页文档中,您首先打印第 1、3 和 5 页。但是当您将打印好的页面重新装入打印机时,您不需要第 5 页。相反,您只需要装入第 1 页和第 3 页。否则,第 4 页将打印在第 5 页的背面,第 2 页将打印在第 3 页的背面,而第 1 页的背面将不会打印任何内容。

为了使事情更容易和更可靠,我编写了一个简单的 Bash 脚本来自动进行双面打印。这基本上是打印奇数页的包装器,提醒我重新装纸(并在需要时删除最后一页),然后打印偶数页。

每当我需要将文档打印为双面时,我首先将文档转换为 PDF。这非常容易做到。在 LibreOffice 中,有一个工具栏图标可以直接导出为 PDF。您也可以在文件—导出为—导出为 PDF下导航以执行相同的操作。或者在任何其他应用程序中,通常都有保存为 PDF功能。如有疑问,GNOME 支持打印到 PDF 文件而不是打印机。

Libre Office toolbar

Export as PDF

工作原理

一旦我保存为 PDF,我就让我的 Bash 脚本完成剩下的工作。这实际上只是自动化了 lpr 命令,使打印更容易。它首先打印奇数页,提示我重新装纸,然后打印偶数页。如果文档的页数是奇数,它还会提醒我在重新装入打印好的页面时删除最后一页。它非常简单。

脚本中唯一的“编程”部分是确定页数,并弄清楚它是偶数还是奇数。这两者都很容易做到。

为了确定页数,我使用了 pdfinfo 命令。这会生成关于 PDF 文档的有用信息。以下是一些示例输出

$ pdfinfo All\ training\ -\ catalog.pdf
Creator:        Writer
Producer:       LibreOffice 6.3
CreationDate:   Fri Oct 18 16:06:07 2019 CDT
Tagged:         no
UserProperties: no
Suspects:       no
Form:           none
JavaScript:     no
Pages:          11
Encrypted:      no
Page size:      612 x 792 pts (letter)
Page rot:       0
File size:      65623 bytes
Optimized:      no
PDF version:    1.5

该输出非常容易解析。为了获得页数,我使用 AWK 单行脚本来查找 Pages: 并打印第二个字段。

pages=$( pdfinfo "$1" | awk '/^Pages:/ {print $2}' )

为了弄清楚这是一个奇数还是偶数,我使用模数 (%) 算术运算符除以 2,并告诉我余数。对于偶数,模 2 始终为零,对于奇数,模 2 始终为一。我使用这个简单的测试来确定文档是否具有奇数页,因此我需要在打印文档的其余部分之前删除最后一页

if [ $(( $pages % 2 )) -ne 0 ] ; then

有了这些,编写 print-duplex.sh Bash 脚本就变得很简单了,只需使用正确的选项调用 lpr 将输出发送到我的打印机 (lpr -P "HP_LaserJet_CP1525nw"),打印奇数页 (-o page-set=odd) 或偶数页 (-o page-set=even),并以相反的顺序打印 (-o outputorder=reverse)。

Bash 脚本

#!/bin/sh
# print-duplex.sh
# simple wrapper to print duplex

cat<<EOF
$1 ($pages pages)
-------------------------------------------------------------------------------
Printing odd pages first
Please wait for job to finish printing...
-------------------------------------------------------------------------------
EOF

lpr -P "HP_LaserJet_CP1525nw" -o page-set=odd "$1"
sleep $pages

cat<<EOF
===============================================================================
Put paper back into the printer in EXACT OUTPUT ORDER (face down in tray)
then press ENTER
===============================================================================
EOF

pages=$( pdfinfo "$1" | awk '/^Pages:/ {print $2}' )

if [ $(( $pages % 2 )) -ne 0 ] ; then
  echo '!! Remove the last page - this document has an odd number of pages'
fi

echo -n '>'
read x

cat<<EOF
-------------------------------------------------------------------------------
Printing even pages
Please wait for job to finish printing...
-------------------------------------------------------------------------------
EOF

lpr -P "HP_LaserJet_CP1525nw" -o page-set=even -o outputorder=reverse "$1"

 

接下来阅读什么
标签
photo of Jim Hall
Jim Hall 是一位开源软件倡导者和开发人员,以 GNOME 的可用性测试以及 FreeDOS 的创始人 + 项目协调员而闻名。

8 条评论

嗨 Jim,不错的文章。一个小错误:`pages` 变量需要在开头设置。

哎呀,这是我在为文章准备时犯的错误。我将 pages= 定义向下移动到 B 面使用的地方(认为这样更容易阅读),但我忘记了开头有一个 echo 语句引用了 $pages,以及上面有一个 sleep 命令,它休眠的秒数等于页数。

很抱歉。是的,pages= 定义应该在脚本的顶部。

我想提出一个修改建议。我经常在 Brother 黑白激光打印机上双面打印。如果我先打印偶数页,我就不必担心最后会有一个“额外”的奇数页。这消除了在打印另一面之前从纸叠中取出奇数页的需要。

那是个好主意。我会试试。谢谢!

回复 作者 Edouard Piche (未验证)

它可以工作,但是,您需要在之后重新排序所有页面(纸叠的第一页将是第 2 页)。为了正常工作,您需要首先以相反的顺序打印偶数页,然后打印奇数页,但是如果您有奇数页,您仍然需要在打印另一面之前添加一个空白页。

回复 作者 Edouard Piche (未验证)

嗨 Jim,

这太棒了 - 我也有一台单面激光打印机... 我以你的脚本为起点并做了这个。我还采用了上面先打印偶数页的评论,这进一步简化了脚本。

这个脚本可以打印用户请求的任意数量的文档。

https://gist.github.com/walterjwhite/4da9fdc077dbbbd8ac855eb66edae1e1

谢谢,

Walter

1 如果它是 bash 脚本,您应该在 hash bang 行中使用 bash

2 bash 可以使用算术表达式作为条件,所以 'if $(( .... )); then ... ; fi' 可以完成这项工作

为了避免从打印机中取出页面(手动工作...)只需打印一张空白页。

代替

if [ $(( $pages % 2 )) -ne 0 ] ; then
echo '!! 删除最后一页 - 此文档有奇数页'
fi

将其更改为

if [ $(( $pages % 2 )) -ne 0 ] ; then
blank_page=$(mktemp)
echo " " > $blank_page
lpr $blank_page
rm $blank_page
fi

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© 2025 open-source.net.cn. All rights reserved.