3

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.

1
  • Don't change your question. If you have a new question you should post it as a new, instead of changing your existing question. Commented Dec 2, 2016 at 19:56

3 Answers 3

5

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 ... ]

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

Comments

3

$@ 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 "$@"

5 Comments

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.
-f expects just a single filename after it, but you're combining all the filename arguments into a single test.
If you have a different question, you should post a new question, not add it to a question that has already been answered.
Yes so how do i fix it. Please. For loop i guess.
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?
1

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

1 Comment

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.

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.