printfile

Submitted scripts and programs
Forum rules
Your own work only.
User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

printfile

Unread post by GekkoP » Thu Dec 12, 2013 9:57 pm

I love printing from command line (thanks to bacon suggestion about lpr). Now, reading The Linux Command Line I found out about lp. It has a lot of options and I'm a lazy bastard, so I wrote this sort of wrapper. Nothing serious, it doesn't check for input errors and I'm pretty sure it could be done in many easier and better ways. After all, my bash scripting skills are pretty low level. But it works for me, so who cares? :)

Do what you want with it.

Code: Select all

#!/bin/bash
#
# Script to make CLI printing easy.

if [ $# -eq 0 ] ; then
    echo "no argument supplied"
    exit
fi

if [ ! -e $1 ]; then
    echo 'file "'$1'" does not exist'
    exit
fi

if [ ! -f $1 ] ; then
    echo '"'$1'" is not a valid file'
    exit
fi

echo
echo 'printfile: script to make CLI printing easy'
echo

echo 'available printers:'
lpstat -a | cut -d ' ' -f 1 > ~/log
sed '/./=' log | sed '/./N; s/\n/ /' # put the line number at the beginning of every line
read -p 'enter selection [1-3] > '
printer=`sed -n ${REPLY}p log | awk '{print $NF}'` # parse selection and keeps only the printer name
rm ~/log

echo
echo -n 'copies > '
read copies

echo
echo 'media size: '
echo "1 a4
2 letter
3 legal"
read -p 'enter selection [1-3] > '
if [[ $REPLY =~ ^[1-3]$ ]]; then
    if [[ $REPLY == 1 ]]; then
	media_size='a4'
    fi
    
    if [[ $REPLY == 2 ]]; then
	media_size='letter'
    fi

    if [[ $REPLY == 3 ]]; then
	media_size='legal'
    fi    
fi

echo
echo 'orientation: '
echo "1 one-sided
2 two-sided-long-edge
3 two-sided-short-edge"
read -p 'enter selection [1-3] > '
if [[ $REPLY =~ ^[1-3]$ ]]; then
    if [[ $REPLY == 1 ]]; then
	orientation='one-sided'
    fi

    if [[ $REPLY == 2 ]]; then
	orientation='two-sided-long-edge'
    fi

    if [[ $REPLY == 3 ]]; then
	orientation='two-sided-short-edge'
    fi
fi

echo
echo 'printing "'$1'"'

#DEBUG
#echo $printer $copies $media_size $orientation

lp -d $printer -n $copies -o media=$media_size -o sides=$orientation $1

machinebacon
Baconator
Posts: 10253
Joined: Thu Sep 16, 2010 11:03 am
Location: Pfälzerwald
Contact:

Re: printfile

Unread post by machinebacon » Fri Dec 13, 2013 4:52 am

that's a superb idea! thanks for sharing!
..gnutella..

User avatar
rhowaldt
Dog
Posts: 4565
Joined: Wed Oct 17, 2012 9:01 am
Contact:

Re: printfile

Unread post by rhowaldt » Fri Dec 13, 2013 9:34 am

cool stuff Gekko, thanks. now let's wait for Xaos to come and make improvements ;)
All statements are true in some sense, false in some sense, meaningless in some sense, true and false in some sense, true and meaningless in some sense, false and meaningless in some sense, and true and false and meaningless in some sense.

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: printfile

Unread post by GekkoP » Fri Dec 13, 2013 9:40 am

^ I actually hope so. :)
Another thing: that wrapper uses only the options I need when printing, but lp has got many other tweaks.

User avatar
rhowaldt
Dog
Posts: 4565
Joined: Wed Oct 17, 2012 9:01 am
Contact:

Re: printfile

Unread post by rhowaldt » Fri Dec 13, 2013 12:27 pm

this is often how scripts are born. you just make something for yourself. the nice thing is sharing it with us all, allowing others to go 'wait, this is great, i want this too, but need option so-and-so', or they go 'this is really nice but you used some silly bash constructions, lemme fix that for you!'
we got just the right people here for that, so it will surely work out :)
All statements are true in some sense, false in some sense, meaningless in some sense, true and false in some sense, true and meaningless in some sense, false and meaningless in some sense, and true and false and meaningless in some sense.

User avatar
wuxmedia
Grasshopper
Posts: 6454
Joined: Wed Oct 17, 2012 11:32 am
Location: Back in Blighty
Contact:

Re: printfile

Unread post by wuxmedia » Fri Dec 13, 2013 2:07 pm

^ the beauty of FOSS, I guess.
"Seek, and Ye shall find"
"Github | Chooons | Site"

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: printfile

Unread post by GekkoP » Fri Dec 13, 2013 5:50 pm

Now with error checking.

Code: Select all

#!/bin/bash
#
# Script to make CLI printing easy.

if [ $# -eq 0 ] ; then
    echo "no argument supplied"
    exit
fi

if [ ! -e $1 ]; then
    echo 'file "'$1'" does not exist'
    exit
fi

if [ ! -f $1 ] ; then
    echo '"'$1'" is not a valid file'
    exit
fi

echo
echo 'printfile: script to make CLI printing easy'
echo

echo 'available printers:'
lpstat -a | cut -d ' ' -f 1 > ~/log
sed '/./=' log | sed '/./N; s/\n/ /' # put the line number at the beginning of every line
read -p 'enter selection [1-3] > '
if [[ ! $REPLY =~ ^[1-3]$ ]]; then
    echo "invalid entry" >&2
    exit 1
fi    
printer=`sed -n ${REPLY}p log | awk '{print $NF}'` # parse selection and keeps only the printer name
rm ~/log

echo
#echo -n 'copies > '
read -p 'copies > '
if [[ $REPLY =~ ^-?[0-9]+$ ]]; then
    copies=$REPLY
else
    echo 'copies must be a number'
    exit 1
fi

echo
echo 'media size: '
echo "1 a4
2 letter
3 legal"
read -p 'enter selection [1-3] > '
if [[ $REPLY =~ ^[1-3]$ ]]; then
    if [[ $REPLY == 1 ]]; then
	media_size='a4'
    fi
    
    if [[ $REPLY == 2 ]]; then
	media_size='letter'
    fi

    if [[ $REPLY == 3 ]]; then
	media_size='legal'
    fi    
else
    echo "invalid entry" >&2
    exit 1
fi

echo
echo 'orientation: '
echo "1 one-sided
2 two-sided-long-edge
3 two-sided-short-edge"
read -p 'enter selection [1-3] > '
if [[ $REPLY =~ ^[1-3]$ ]]; then
    if [[ $REPLY == 1 ]]; then
	orientation='one-sided'
    fi

    if [[ $REPLY == 2 ]]; then
	orientation='two-sided-long-edge'
    fi

    if [[ $REPLY == 3 ]]; then
	orientation='two-sided-short-edge'
    fi
else
    echo "invalid entry" >&2
    exit 1
fi

echo
echo 'printing "'$1'"'

#DEBUG echo $printer $copies $media_size $orientation

lp -d $printer -n $copies -o media=$media_size -o sides=$orientation $1

User avatar
xaos52
The Good Doctor
Posts: 190
Joined: Thu Aug 15, 2013 11:59 am
Location: Eernegem, Belgium

Re: printfile

Unread post by xaos52 » Fri Dec 13, 2013 6:16 pm

Code: Select all

if [[ $REPLY =~ ^[1-3]$ ]]; then
    if [[ $REPLY == 1 ]]; then
   media_size='a4'
    fi
   
    if [[ $REPLY == 2 ]]; then
   media_size='letter'
    fi

    if [[ $REPLY == 3 ]]; then
   media_size='legal'
    fi   
else
    echo "invalid entry" >&2
    exit 1
fi

for mutually exclusive options, better use
if
elif
elif
else
fi

or, better still

case
esac

I just quickly skimmed through the script. Have not tried to run it.
As a matter of fact I have not printed anything for ages now :)

xaos
Connected. Take this REPL, brother, and may it serve you well.

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: printfile

Unread post by GekkoP » Fri Dec 13, 2013 6:29 pm

Thank you, I'll try with case/esac and see what I can do. Feel free to do whatever you want with it, it's always a matter of learning something new to me. ;)

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: printfile

Unread post by GekkoP » Fri Dec 13, 2013 6:39 pm

It definitely looks better

Code: Select all

#!/bin/bash
#
# Script to make CLI printing easy.


if [ -z $1 ] ; then
    echo "no file specified"
    exit 1
elif [ ! -e $1 ]; then
    echo 'file "'$1'" does not exist'
    exit 1
elif [ ! -f $1 ] ; then
    echo '"'$1'" is not a valid file'
    exit 1
fi

echo
echo 'printfile: script to make CLI printing easy'
echo

echo 'available printers:'
lpstat -a | cut -d ' ' -f 1 > ~/log
sed '/./=' log | sed '/./N; s/\n/ /' # put the line number at the beginning of every line
read -p 'enter selection [1-3] > '
if [[ ! $REPLY =~ ^[1-3]$ ]]; then
    echo "invalid entry" >&2
    exit 1
fi    
printer=`sed -n ${REPLY}p log | awk '{print $NF}'` # parse selection and keeps only the printer name
rm ~/log

echo
read -p 'copies > '
if [[ $REPLY =~ ^-?[0-9]+$ ]]; then
    copies=$REPLY
else
    echo 'copies must be a number'
    exit 1
fi

echo
echo 'media size: '
echo "1 a4
2 letter
3 legal"
read -p 'enter selection [1-3] > '
case $REPLY in
1)
media_size='a4'
;;
2)
media_size='letter'
;;
3)
media_size='legal'
;;
*)    
echo "invalid entry" >&2
exit 1
;;
esac

echo
echo 'orientation: '
echo "1 one-sided
2 two-sided-long-edge
3 two-sided-short-edge"
read -p 'enter selection [1-3] > '
case $REPLY in
1)
orientation='one-sided'
;;
2)
orientation='two-sided-long-edge'
;;
3)
orientation='two-sided-short-edge'
;;
*)
echo "invalid entry" >&2
exit 1
;;
esac

echo
echo 'printing "'$1'"...'

#DEBUG echo $printer $copies $media_size $orientation
lp -d $printer -n $copies -o media=$media_size -o sides=$orientation $1

User avatar
johnraff
Sperminator
Posts: 199
Joined: Wed Oct 17, 2012 6:38 pm
Location: Japan
Contact:

Re: printfile

Unread post by johnraff » Sat Dec 14, 2013 4:55 am

Just a question of style, I guess, but you can reduce the number of times 'echo' is called by using more linebreaks inside quotes. eg This

Code: Select all

echo
echo 'media size: '
echo "1 a4
2 letter
3 legal"
could be this

Code: Select all

echo'
media size: 
1 a4
2 letter
3 legal'
All code is one.

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: printfile

Unread post by GekkoP » Sat Dec 14, 2013 9:32 am

^ nice, very nice.

machinebacon
Baconator
Posts: 10253
Joined: Thu Sep 16, 2010 11:03 am
Location: Pfälzerwald
Contact:

Re: printfile

Unread post by machinebacon » Sun Dec 15, 2013 4:52 am

Hey, if you usually print A4, one-sided, you can make this the default choice, so you just enter the number of copies, then Enter and Enter, and off it goes. (If you add 'dialog' or 'whiptail', you can do the same with the default choice)
..gnutella..

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: printfile

Unread post by GekkoP » Sun Dec 15, 2013 11:33 am

Interesting, I'll try that thanks.

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: printfile

Unread post by GekkoP » Mon Dec 16, 2013 11:36 am

Added default, fixed a path. All yours.

Code: Select all

#!/bin/bash
#
# Script to make CLI printing easy.

if [ -z $1 ] ; then
    echo "no file specified"
    exit 1
elif [ ! -e $1 ]; then
    echo 'file "'$1'" does not exist'
    exit 1
elif [ ! -f $1 ] ; then
    echo '"'$1'" is not a valid file'
    exit 1
fi

echo '
printfile: script to make CLI printing easy
'
echo 'available printers:'
lpstat -a | cut -d ' ' -f 1 > ~/log
sed '/./=' ~/log | sed '/./N; s/\n/ /' # put the line number at the beginning of every line
read -p 'enter selection [1-3] > '
if [[ ! $REPLY =~ ^[1-3]$ ]]; then
    echo "invalid entry" >&2
    exit 1
fi    
printer=`sed -n ${REPLY}p log | awk '{print $NF}'` # parse selection and keeps only the printer name
rm ~/log

echo
read -p 'copies > '
if [[ $REPLY =~ ^-?[0-9]+$ ]]; then
    copies=$REPLY
else
    echo 'copies must be a number'
    exit 1
fi

echo '
media size [default a4]:
1 a4
2 letter
3 legal'
read -p 'enter selection [1-3] > '
case $REPLY in
1)
media_size='a4'
;;
2)
media_size='letter'
;;
3)
media_size='legal'
;;
'')
media_size='a4'
;;
*)    
echo "invalid entry" >&2
exit 1
;;
esac

echo '
orientation [default two-sided-long-edge]: 
1 one-sided
2 two-sided-long-edge
3 two-sided-short-edge'
read -p 'enter selection [1-3] > '
case $REPLY in
1)
orientation='one-sided'
;;
2)
orientation='two-sided-long-edge'
;;
3)
orientation='two-sided-short-edge'
;;
'')
orientation='two-sided-long-edge'
;;
*)
echo "invalid entry" >&2
exit 1
;;
esac

echo '
printing "'$1'"...'

#DEBUG echo $printer $copies $media_size $orientation
lp -d $printer -n $copies -o media=$media_size -o sides=$orientation $1

User avatar
xaos52
The Good Doctor
Posts: 190
Joined: Thu Aug 15, 2013 11:59 am
Location: Eernegem, Belgium

Re: printfile

Unread post by xaos52 » Mon Dec 16, 2013 12:48 pm

Remarks:

1. Your script needs lpstat. Not everyone has it installed. You must handle this gracefully.
2. Handle the situation where there are no printer available.
3. Using $HOME/log as a temp file is dangerous. Perhaps there is another log file in there that you want to keep.
Use 'tempfile' to create unique tmp files
4. I havent tested any more because I don't have a printer attached, but the rest of the script looks OK.
Connected. Take this REPL, brother, and may it serve you well.

User avatar
GekkoP
Emacs Sancho Panza
Posts: 5878
Joined: Tue Sep 03, 2013 7:05 am

Re: printfile

Unread post by GekkoP » Mon Dec 16, 2013 1:39 pm

^ precious tips, thanks, I'll see what I can do.

User avatar
johnraff
Sperminator
Posts: 199
Joined: Wed Oct 17, 2012 6:38 pm
Location: Japan
Contact:

Re: printfile

Unread post by johnraff » Tue Dec 17, 2013 6:32 pm

Just had a thought - you might consider using 'select' ('help select') for choosing the printer. Something like this?

Code: Select all

PS3='choose printer> '
select printer in $(lpstat -a | cut -d ' ' -f 1)
do 
    [[ $printer ]] && break || echo 'invalid entry
'
done
$printer now holds the printer name.
All code is one.

Post Reply