How to use bash file testing flags?
bash if flags linux unix posix
This entry is reference copy of this great StackOverflow answer with some additional examples and description.
Bash File Testing
-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:
#!/bin/bash
file=./file
if [ -e "$file" ]; then
echo "File exists"
else
echo "File does not exist"
fi
A test expression can be negated by using
the !
operator
#!/bin/bash
file=./file
if [ ! -e "$file" ]; then
echo "File does not exist"
else
echo "File exists"
fi
The flags can be combined using &&
expression. Each test need to be in it's own square brackets.
Example below shows how to check if file is readable and
writable:
#!/bin/bash file=./file if [ -r "$file" ] && [ -w "$file" ]; then echo "File is readable and writable" else echo "File is not readable or writable" fi
Check if it's real directory, not symlinked one:
#!/bin/bash file=./file if [ -d "$file" ] && [ ! -L "$file" ]; then echo "Real directory" else echo "Not real directory, possibly symbolic link" fi
Further Explanation of Each Flag
-
-b filename
: Checks for block special files like hard drives and other block devices. These are files that provide buffered I/O access. -
-c filename
: Checks for character special files such as terminals or keyboards. These files provide unbuffered, direct access to hardware devices. -
-d directoryname
: Verifies if the specified directory exists. This will also evaluate totrue
for symlinks to directories. -
-e filename
: Checks for the existence of a file regardless of its type. -
-f filename
: Determines if the specified file is a regular file (not a directory, device, etc.). -
-G filename
: Confirms if the file exists and is owned by the effective group ID of the user running the script. -
-g filename
: Checks if the set-group-ID (SGID) bit is set on the file, which means it will be executed with the permissions of the group that owns the file. -
-k filename
: Tests if the sticky bit is set, which affects directory deletion permissions. -
-L filename
: Checks if the file is a symbolic link. -
-O filename
: Verifies if the file is owned by the effective user ID. -
-r filename
: Tests if the file is readable by the user running the test. -
-S filename
: Checks if the file is a socket, which is used for inter-process communication. -
-s filename
: Determines if the file size is greater than zero. -
-u filename
: Checks if the set-user-ID (SUID) bit is set, which means the file will be executed with the permissions of the owner of the file. -
-w filename
: Tests if the file is writable by the user running the test. -
-x filename
: Determines if the file is executable by the user running the test.