使用这个简单的 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 脚本来自动进行双面打印。这基本上是 lpr 命令的包装器,使打印更容易。它首先打印奇数页,提示我重新装纸(并在需要时删除最后一页),然后打印偶数页。

每当我需要将文档双面打印时,我首先将文档转换为 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}' )

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

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 面使用它的位置(认为这样会更容易阅读),但我忘记了开头有一个引用 $pages 的 echo 语句,以及上面有一个 sleep 命令,该命令的睡眠秒数等于页数。

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

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

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

回复 作者: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本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.