Unix bash error - binary operator expected

10,805

Solution 1

Doing it another way: just ask how many parameters were passed:

...
if [ $# -eq 0 ]
...

You get the error in your code because the $@ variable expands to multiple words, which leaves the test command looking like this:

[ -z parm1 parm2 parm3 ... ]

Solution 2

$@ is expanding to all the arguments, with spaces between them, so it looks like:

if [ -z file1 file2 file3 ]

but -z expects just one word after it. You need to use $* and quote it, so it expands into a single word:

if [ -z "$*" ]

This expands into:

if [ -z "file1 file2 file3" ]

Or just check the number of arguments:

if [ $# -eq 0 ]

You should also put this check before the for loop. And you should quote the argument in the for loop, so you don't have problems with filenames that have spaces:

for file in "$@"

Solution 3

Wrap your parameters in double quotes to avoid word splitting and pathname expansion:

for file in "$@"
do
    chmod 755 "$file"
done

if [ -z "$*" ] # Use $* instead of $@ as "$@" expands to multiply words.
then
        echo "Error. No argument."
        exit "$ERROR_CODE_1"
fi

You can however change the code a little:

for file # No need for in "$@" as it's the default
do
    chmod 755 "$file"
done

if [ "$#" -eq 0 ] # $# Contains numbers of arguments passed
then
    >&2 printf 'Error. No argument.\n'
    exit "$ERROR_CODE_1" # What is this?
fi
Share:
10,805
pogba123
Author by

pogba123

Updated on June 04, 2022

Comments

  • pogba123
    pogba123 almost 2 years

    So below is the code i have in my bash script. I'm getting an error saying binary operator expected when i give the command 2 arguments (doesnt give error when i give 1 argument). It does change the file permissions when i give 2 arguments because i can see it when i do ls -l but it still gives me this error. How do i fix it?

    for file in $@
    do
        chmod 755 $file
    done
    
    if [ -z $@ ]
    then
            echo "Error. No argument."
            exit $ERROR_CODE_1
    fi
    

    i have added this now

    if [ ! -f "$*" ]
    then
           echo "Error. File does not exist"
           exit $ERROR_NO_FILE
    fi
    

    But now when i enter more than 1 argument it just does everything in the if statement (i.e. prints error.file does not exist) even when the file does exist.

  • pogba123
    pogba123 over 7 years
    i have updated my code above in the question box and am getting a different error please can you help me. i am a beginner and need help.
  • pogba123
    pogba123 over 7 years
    i have updated my code above in the question box and am getting a different error please can you help me. i am a beginner and need help.
  • Barmar
    Barmar over 7 years
    -f expects just a single filename after it, but you're combining all the filename arguments into a single test.
  • Barmar
    Barmar over 7 years
    If you have a different question, you should post a new question, not add it to a question that has already been answered.
  • pogba123
    pogba123 over 7 years
    Yes so how do i fix it. Please. For loop i guess.
  • Barmar
    Barmar over 7 years
    I don't understand what you want to do. You should use if [ ! -f "$file" ] inside the for loop. Why would you test the entire argument list?