0

I have written a shell script for printing book:

#!/bin/sh
if [ -z "$1" ]
then
    exit 1
fi
filename=$1
options=""
mode="color"
first=""
last=""
pages="All pages from"
shift
until [ -z "$1" ]
do
    if [ $1 = "gray" -o $1 = "grey" -o $1 = "grayscale" -o $1 = "greyscale" ]
    then
        options=" -o ColorModel=KGray"
        mode=$1
    elif [ $1 = "from" ]
    then
        shift
        first="$1"
    elif [ $1 = "to" ]
    then
        shift
        last="$1"
    fi
    shift
done
if [ $first -o $last ]
then
    pages="Pages"
    if [ $first ]
    then
        pages="$pages $first"
        first=" -f $first"
    else
        pages="$pages 1"
    fi
    if [ $last ]
    then
        pages="$pages to $last"
        last=" -l $last"
    else
        pages="$pages to last"
    fi
    pages="$pages from"
fi
echo -n "$pages $filename will be printed in $mode mode. If it's OK, put paper in your printer and press ENTER. Else press CTRL+C. "
read ack
pdftops$first$last -expand $filename - | psbook | psnup -2 > tmp.ps
psselect -o tmp.ps | lpr$options
echo -n "Wait for the end of printing, then take printed pages, put them back in printer to print on other side and press ENTER again."
read ack
psselect -e -r tmp.ps | lpr$options
rm tmp.ps
exit 0

When I saved this code to file "print-book" and ran it like:

print-book test.pdf gray

I got this:

Pages 1 to last from test.pdf will be printed in gray mode. If it's OK, put paper in your printer and press ENTER. Else press CTRL+C

i.e. condition "$first -o $last" was true. But if check "$first" and "$last" separately in this place, they both are false.

How is this possible?

1 Answer 1

3

If $first and $last are empty, [ $first -o $last ] will be evaluated as [ -o ], which is not what you want.

You should instead use [ "$first" -o "$last" ], which is equivalent to [ "" -o "" ].


Never use variables without quoting them (unless you know what you're doing): the results will be unexpected most of the times.

Also, test weird behaviors interactively in the command line: just input [ $a -o $b ] && echo y to quickly see what's going on and being able to play with your variables.

Sign up to request clarification or add additional context in comments.

1 Comment

The POSIX standard recommends against use -o for this very reason, and suggests using [ ... ] || [ ... ] in place of [ ... -o ... ].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.