dm-kiselev
dm-kiselev

Reputation: 177

Logical OR error in Linux shell script

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?

Upvotes: 0

Views: 60

Answers (1)

peoro
peoro

Reputation: 26060

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.

Upvotes: 3

Related Questions