Wizard
Wizard

Reputation: 22083

Parameters work properly when remove their quoting

I am puzzled about the verbose of quoting in the script. Take an example from the instruction I followed:

min_val=1
max_val=100
int=50
if [[ "$int" =~ ^-?[0-9]+$ ]]; then
    if [[ "$int" -ge "$min_val" &&  "$int" -le "$max_val" ]]; then
        echo "$int is within $min_val to $max_val."
    else
        echo "$int is out of range."
    fi
else
    echo "int is not an integer." >&2
    exit 1
fi

Run it and come by:

$ bash test_integer3.sh
50 is within 1 to 100.

When I removed all the quoting in testing:

if [[ $int =~ ^-?[0-9]+$ ]]; then
    if [[ $int -ge $min_val &&  $int -le $max_val ]]; then
        echo "$int is within $min_val to $max_val."
    else
        echo "$int is out of range."
    fi
else
    echo "int is not an integer." >&2
    exit 1
fi

It's still working properly.

$ bash test_integer3.sh
50 is within 1 to 100.

Why should live with the habit of writing redundant quoting?

Upvotes: 1

Views: 67

Answers (3)

Inian
Inian

Reputation: 85590

The real problem comes when you start to use [ command over [[ in your scripts. [[ is bash's improvement to the [ command. It has several enhancements that make it a better choice to write scripts targeting bash.

One such improvement would be that you no longer have to quote variables because [[ handles empty strings and strings with white-space more intuitively. For example consider your script written with [ for the un-quoted case and for discussions sake, one of your variables is empty

#!/usr/bin/env bash

min_val=
max_val=
int=50

if [[ $int =~ ^-?[0-9]+$ ]]; then
    if [ $int -ge $min_val -a  $int -le $max_val ]; then
        echo "$int is within $min_val to $max_val."
    else
        echo "$int is out of range."
    fi
else
    echo "int is not an integer." >&2
    exit 1
fi

One thing to note is I've re-written the combined conditional using the -a syntax since [ does not support && operator within but could be combined using && as [ $int -ge $min_val ] && [ $int -le $max_val ]

You would see things going bad and seeing errors as below which means that one of the conditionals involving -le is gone wrong on seeing an empty string.

1_script.sh: line 7: [: -a: integer expression expected
50 is out of range.

whereas with same code for undefined variables and replacing the expression to use [[ would gracefully handle the empty strings to produce just an incorrect result as

50 is out of range.

So to sum it up, from the many advantages over using [[, the particular advantage on your case is to handle variables if there could be empty strings in your conditionals.

Upvotes: 3

AncientRoman
AncientRoman

Reputation: 123

In your piece of code you don't need quotes as you discovered. However, using quotes is considered "good practice" because unexpected things can happen without quotes. For example if you run the code with int equal to say "foo bar" you might get some strange results without quotes. It is like the double and triple equals in JavaScript. You could probably get away with only double equals but some unexpected results might occur.

Upvotes: 1

haccks
haccks

Reputation: 106012

Quoting is used to to stop the word splitting. In the case above it is not necessary but consider a case like this: you have a directory and having theses files file1.txt, file2.txt, old.txt and file1 old.txt.
If you wish to remove the file file1 old.txt and run the command

rm file1 old.txt  

then it will remove the file old.txt instead of what you expected.

Upvotes: 1

Related Questions