Bash – Checking and changing file permission with script

bashscriptingshell-script

I'm new to bash and I can't get a script working. This is the code that I have:

#!/bin/bash
file=~/scripts/text.txt

if [ -e $file ]
then echo "The file exists"

elif [ ! -e $file ]
then echo "The file does NOT exist"

fi

sleep 1s

if [ ! -w $file ]
then { sudo chmod u+w $file; } && { echo "The file is now writable"; }

elif [ -w $file ]
then echo "The file is already writable"
fi

The top part of the script, that checks if the file exists, works just fine. The bottom part, that checks if the file is writable, partly works. It will change the permissions of the file. But after that, with write permissions enabled, it will still echo "The file is now writable" instead of "The file is already writable"

Like I said, I'm new to bash so any help would be appreciated. Please keep it simple, because if statements are about as complex as I can go with my current knowledge.

Best Answer

It's weird that you're using sudo to change the permissions on the file, even though it's in your home directory. Does the file belong to you? chmod u+w only gives write permission to the owner of the file. If you are the owner, you don't need sudo. If you aren't the owner, you do need sudo, but chmod u+w only gives the owner write permission, it doesn't grant you permission to write to the file. So after running chmod u+w, the file is still not writable by you, which is what [ -w … ] tests.

Run ls -l ~/scripts/text.txt to check the ownership and permissions on the file.

Aside from this, always put double quotes around variable substitutions. (Or you can learn all the rules and make your script hard to maintain by people who don't know all the rules.) Annoyingly, $file in shell syntax doesn't mean “take the value of the variable file”, it means “take the value of the variable file, parse it as a list of wildcard patterns, and replace each pattern by the list of matching files if there are matching files”. This extra stuff is turned off if the substitution happens inside double quotes: "$file" means “take the value of the variable file”.

Also, you don't need all these braces.

if [ ! -w "$file" ]
then
  sudo chmod u+w "$file" && echo "The file is now writable"
elif [ -w "$file" ]
then
  echo "The file is already writable"
fi

Since [ -w "$file" ] is the negation of [ ! -w "$file" ], the elif test will always succeed if it is reached. (Unless there's a race condition, in which case the elif test that tests the same condition again may return a different result, which is bad.) So you can and should simplify this to

if [ ! -w "$file" ]
then
  sudo chmod u+w "$file" && echo "The file is now writable"
else
  echo "The file is already writable"
fi
Related Question