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 needsudo
, butchmod u+w
only gives the owner write permission, it doesn't grant you permission to write to the file. So after runningchmod 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 variablefile
”, it means “take the value of the variablefile
, 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 variablefile
”.Also, you don't need all these braces.
Since
[ -w "$file" ]
is the negation of[ ! -w "$file" ]
, theelif
test will always succeed if it is reached. (Unless there's a race condition, in which case theelif
test that tests the same condition again may return a different result, which is bad.) So you can and should simplify this to