Checking files & directories in your Bash script

It’s good practise to perform all kinds of tests on files that you are processing in a Bash script, in particular if it is a file that the user has provided. Here is a reminder of the test flags you can use as part of the test command:

Switches to check:

-b filename – Block special file
-c filename – Special character file
-d directoryname – Check for directory Existence
-e filename – Check for file existence, regardless of type (node, directory, socket, etc.)
-f filename – Check for regular file existence not a directory
-G filename – Check if file exists and is owned by effective group ID
-G filename set-group-id – True if file exists and is set-group-id
-k filename – Sticky bit
-L filename – Symbolic link
-O filename – True if file exists and is owned by the effective user id
-r filename – Check if file is a readable
-S filename – Check if file is socket
-s filename – Check if file is nonzero size
-u filename – Check if file set-user-id bit is set
-w filename – Check if file is writable
-x filename – Check if file is executable

How to use:

if [[ -e "${file}" ]] ; then
    echo "File exists"
    echo "File does not exist"

test expression can be negated by using the ! operator

if [[ ! -e "${file}" ]] ; then
    echo "File does not exist"
    echo "File exists"

Source: GroundZero @ StackOverflow
Note: To be risk-adverse I like to use double brackets [[ ]] around the tests and brackets {} around the variable names.

Additionally it might be useful here to learn additional comparison operators:

[ ( EXPR ) ] Returns the value of EXPR. This may be used to override the normal precedence of operators.
[ EXPR1 -a EXPR2 ] True if both EXPR1 and EXPR2 are true.
[ EXPR1 -o EXPR2 ] True if either EXPR1 or EXPR2 is true.
[ -z STRING ] True of the length if “STRING” is zero.
[ -n STRING ] or [ STRING ] True if the length of “STRING” is non-zero.
[ STRING1 == STRING2 ] True if the strings are equal. “=” may be used instead of “==” for strict POSIX compliance.
[ STRING1 != STRING2 ] True if the strings are not equal.
[ ARG1 OP ARG2 ] “OP” is one of -eq-ne-lt-le-gt or -ge. These arithmetic binary operators return true if “ARG1” is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to “ARG2”, respectively. “ARG1” and “ARG2” are integers.