-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
lpd_cli.sh
executable file
·186 lines (161 loc) · 5.58 KB
/
lpd_cli.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#!/bin/bash
###############
# Automatic manual duplex printing (command-line interface)
# (C) 2021 Natalie Clarius <[email protected]>
# GNU General Public License v3.0
###############
###############
# configuration
###############
printer=Epson_Stylus_SX440
order=1
###############
# initialization
###############
# usage
if [ $# -eq 0 ] # no arguments given
then
echo "Usage: lpd <F> [<S> <E> <M> <C>]"
echo " F: file name"
echo " S: start of page range to print"
echo " E: end of page range to print"
echo " M: multipage: number of pages per side"
echo " C: color mode: 'c': colored (default), 'g': gray scale"
echo "Either no or options, only S and R, or all options have to be provided."
echo "Examples:"
echo " $ lpd example.pdf # print example.pdf"
echo " $ lpd example.pdf 4 10 # print example.pdf pages 4-10"
echo " $ lpd example.pdf 4 10 2 g # print example.pdf pages 4-10 with two pages per side in gray scale"
exit
fi
# initial variables
filename=$1 # file name
num_pages=$(pdfinfo $1 | grep Pages | awk '{print $2}') # number of pages in document
[ -z "$2" ] && start=1 || start=$2 # start of page range (default: 1)
[ -z "$3" ] && end=$num_pages || end=$3 # end of page range (default: num_pages)
[ -z "$4" ] && multi=1 || multi=$4 # pages per side (default: 1)
([ -z "$5" ] || [ "$5" == "c" ]) && color=true || color=false # color
# get page ranges
first=$(( ($start+$multi-1)/$multi )) # first multipage to print
last=$(( ($end+$multi-1)/$multi )) # last multipage to print
start_=$(( (($first-1)*$multi)+1 )) # start of printed page range
end_=$(( $last*$multi )) # end of printed page range
num_sheets=$(( $last-$first+1 )) # number of output
# sort into front, back and remainder pages
front_=()
back_=()
i=1
for ((p=first; p<=last; p++))
do
if ((i % 2))
then
front_+=($p) # odd multipages to front
else
back_+=($p) # even multipages to back
fi
i=$((i+1))
done
if [[ ${#back_[@]} -eq 0 ]] # only single front page
then
backapges=false
remainder=false
else
backpages=true
if (( ${#front_[@]} > ${#back_[@]} )) # more front than back pages
then
remainder=true
fi
fi
# convert page range to comma-separated string
function join_by { local IFS="$1"; shift; echo "$*"; }
front=$(join_by , "${front_[@]}")
back=$(join_by , "${back_[@]}")
# notify user of initialization
echo "Duplex print"
echo "File: $filename"
echo "Page range: $start_-$end_"
echo "Pages per sheet: $multi"
echo "Number of pages: $num_sheets"
echo "Colored: $color"
echo "Continue (y/n)?"
read confirm
if [ "$confirm" != "y" ] && [ "$confirm" != "" ]
then
echo "Cancelled"
exit 3
fi
echo "Printing ..."
echo ""
###############
# printing
###############
# execute print job
send_print_job () { # send print job and return job id
# $1: file name, $2: page range, $3: multi, $4: reverse, $5: color
printrequest="lp -d $printer" # basic print request
if [[ $# -eq 0 ]]
then
echo $(lp -d $printer <<< "" | sed -e "s/request id is \(.*\) (0 file(s))/\1/") # last empty backpage
else
printrequest="lp -d $printer" # basic print request
printrequest+=" -o page-ranges=$2" # page range
if [[ "$3" = true ]]; then printrequest+=" -o number-up=$3"; fi # multi-page print
if [[ "$4" = true ]]; then printrequest+=" -o outputorder=reverse"; fi # reverse order
if [[ "$5" = false ]]; then printrequest+=" -o Color=Grayscale"; fi # color
printrequest+=" $1 " # file name
echo $($printrequest | sed -e "s/request id is \(.*\) (1 file(s))/\1/")
fi
}
# monitor print job status
monitor_print_job () {
# $1: job id
completed=false
until $completed
do
sleep 5 # check only every 5 seconds
completed_jobs=$(lpstat -W completed $printer | awk "{print \$1}") # get completed print jobs
if [[ "$completed_jobs" == *"$1"* ]]; then completed=true; fi # check if current job is among completed; if yes, proceed
done
}
# print
if [[ "$order" == 1 ]] # order variant 1: first front pages, then back pages, then last empty back page
then
# print front pages
reverse=false
front_job=$(send_print_job $filename $front $multi $reverse $color)
monitor_print_job $front_job
if [[ "$backpages" = true ]]
then
# prompt user to turn paper
echo "Please turn the paper, then press Enter."
read confirm
# print back pages
reverse=false
back_job=$(send_print_job $filename $back $multi $reverse $color)
monitor_print_job $back_job
# print last empty back page
if [[ "$remainder" = true ]]
then
remainder_job=$(send_print_job)
monitor_print_job $remainder_job
fi
fi
elif [[ "$order" == 2 ]] # order variant 2: first reversed back pages, then front pages
then
if [[ "$backpages" = true ]]
then
# print back pages
reverse=true
back_job=$(send_print_job $filename $back $multi $reverse $color)
monitor_print_job $back_job
# prompt user to turn paper
echo "Please turn the paper, then press Enter."
read confirm
fi
# print front pages
reverse=false
front_job=$(send_print_job $filename $front $multi $reverse $color)
monitor_print_job $front_job
fi
# notify user of completion
echo "Done"