The Linux if command can help find types, permissions, and content of files, among many other things. Credit: Stokkete / Shutterstock There are a lot more ways to check files using if commands than many of us realize. Although this information is included in the bash man page, that man page has thousands of lines and you could easily find yourself paging down more than 100 times to reach it. This post, provides information on each option and examples for some of the most useful ones. Checking if a file exists One of the most commonly used tests for checking on files is if [ -f filename ]. This test will result in true if the file exists and is a regular file—not a directory or a symbolic link. You might use it like this: $ if [ -f myfile.txt ]; then > echo myfile.txt exists > else > touch myfile.txt > fi myfile.txt exists The command above would create the file using the touch command if it doesn’t already exist. The following command would only tell you if the file is or isn’t a regular file: $ if [ -f /home/shs ]; then > echo file exists > else > echo file is not a regular file > fi file is not a regular file If you want to know whether a file exists regardless of what kind of file it is, you can use the -a or the -e test. $ if [ -e symlink ]; then > echo file exists > else > echo no such file > fi file exists Checking if a file is a directory Using -d will tell you if a file is a directory. $ if [ -d /home/shs ]; then > echo directory > else > echo not a directory > fi directory Reversing the effect of if tests You can reverse the effects of an if test by preceding the test with a ! (not) sign. To test if a file has content, you could use a command like this one: $ if [ -s emptyfile ]; then > echo has content > else > echo empty > fi To change the command above to test whether the file is empty, do this: $ if [ ! -s emptyfile ]; then > echo empty > else > echo has content > fi This of -s as “some content” and ! -s as “no content”. The ! can be used with any of the if tests. Here are a few examples: if [ ! -d file ] Checking file permissions Other especially useful tests can tell you if you can read a file, write to a file or execute a file. $ if [ -r ~/bin/loop ]; then > echo readable > fi readable $ if [ -w ~/bin/loop ]; then > echo writable > fi writable $ if [ -x ~/bin/loop ]; then > echo executable > fi executable Note that these tests only check your access rights, not anyone else’s and that the files tested above are all in the bin directory in the user’s home directory (~/bin). You can also check whether a file is a character-special file, if its SGID (set group ID) bit is set and if its SUID (set user ID) bit is set. The chmod command sets the bits being tested in the second and third examples. $ if [ -c /dev/tty11 ]; then > echo character-special file > fi character-special file $ chmod 7755 yn $ if [ -g yn ]; then > echo SGID set > fi SGID set $ if [ -u yn ]; then > echo SUID set > fi SUID set Checking if a file was recently modified The -N checks whether a file’s content was modified since the last time it was read. The echo command below adds a line, so the second test result is the opposite of the first. $ if [ -N testfile ]; then > echo file has been modified > else > echo file not modified > fi file not modified $ echo “——-“ >> testfile $ $ if [ -N testfile ]; then > echo file has been modified > else > echo file not modified > fi file has been modified Comparing file ages You can use if tests to determine if one file has been changed more recently than another. The -nt test means “newer than”. $ if [ file1 -nt file2 ]; then > echo file1 is newer > else > echo file2 is newer > fi file2 is newer Using -ot (older than) in place of -nt has the opposite effect. All if commands for checking the status of files Here is a list of all the if tests that check the status of files. Just remember that any can be reversed with a ! symbol (e.g., if [ ! file1 -ot file2 ]). if [ -a FILE ] — True if FILE exists if [ -b FILE ] — True if FILE exists and is a block-special file if [ -c FILE ] — True if FILE exists and is a character-special file if [ -d FILE ] — True if FILE exists and is a directory if [ -e FILE ] — True if FILE exists if [ -f FILE ] — True if FILE exists and is a regular file if [ -g FILE ] — True if FILE exists and its SGID bit is set if [ -h FILE ] — True if FILE exists and is a symbolic link if [ -k FILE ] — True if FILE exists and its sticky bit is set if [ -p FILE ] — True if FILE exists and is a named pipe (FIFO) if [ -r FILE ] — True if FILE exists and is readable if [ -s FILE ] — True if FILE exists and has a size greater than zero if [ -t FD ] — True if file descriptor FD is open and refers to a terminal if [ -u FILE ] — True if FILE exists and its SUID (set user ID) bit is set if [ -w FILE ] — True if FILE exists and is writable if [ -x FILE ] — True if FILE exists and is executable if [ -O FILE ] — True if FILE exists and is owned by the effective user ID if [ -G FILE ] — True if FILE exists and is owned by the effective group ID if [ -L FILE ] — True if FILE exists and is a symbolic link if [ -N FILE ] — True if FILE exists and has been modified since it was last read if [ -S FILE ] — True if FILE exists and is a socket if [ FILE1 -nt FILE2 ] — True if FILE1 has been changed more recently than FILE2 or if FILE1 exists and FILE2 does not if [ FILE1 -ot FILE2 ] — True if FILE1 is older than FILE2 or if FILE2 exists and FILE1 does not if [ FILE1 -ef FILE2 ] — True if FILE1 and FILE2 refer to the same device and inode numbers if test result [ -a FILE ] True if FILE exists [ -b FILE ] True if FILE exists and is a block-special file [ -c FILE ] True if FILE exists and is a character-special file [ -d FILE ] True if FILE exists and is a directory [ -e FILE ] True if FILE exists [ -f FILE ] True if FILE exists and is a regular file [ -g FILE ] True if FILE exists and its SGID bit is set [ -h FILE ] True if FILE exists and is a symbolic link [ -k FILE ] True if FILE exists and its sticky bit is set [ -p FILE ] True if FILE exists and is a named pipe (FIFO) [ -r FILE ] True if FILE exists and is readable [ -s FILE ] True if FILE exists and has a size greater than zero [ -t FD ] True if file descriptor FD is open and refers to a terminal [ -u FILE ] True if FILE exists and its SUID (set user ID) bit is set [ -w FILE ] True if FILE exists and is writable [ -x FILE ] True if FILE exists and is executable [ -O FILE ] True if FILE exists and is owned by the effective user ID [ -G FILE ] True if FILE exists and is owned by the effective group ID [ -L FILE ] True if FILE exists and is a symbolic link [ -N FILE ] True if FILE exists and has been modified since it was last read [ -S FILE ] True if FILE exists and is a socket [ FILE1 -nt FILE2 ] True if FILE1 has been changed more recently than FILE2 or if FILE1 exists and FILE2 does not [ FILE1 -ot FILE2 ] True if FILE1 is older than FILE2 or if FILE2 exists and FILE1 does not [ FILE1 -ef FILE2 ] True if FILE1 and FILE2 refer to the same device and inode numbers —> Wrap-Up There are a lot of ways to check and verify files on the command line or within scripts. Some of these options can help ensure that your scripts check files before trying to use them or avoid overwriting them if they already exist. These tests often play an important role when using scripts to automate your work. Related content how-to Compressing files using the zip command on Linux The zip command lets you compress files to preserve them or back them up, and you can require a password to extract the contents of a zip file. By Sandra Henry-Stocker May 13, 2024 4 mins Linux opinion NSA, FBI warn of email spoofing threat Email spoofing is acknowledged by experts as a very credible threat. By Sandra Henry-Stocker May 13, 2024 3 mins Linux how-to The logic of && and || on Linux These AND and OR equivalents can be used in scripts to determine next actions. By Sandra Henry-Stocker May 02, 2024 4 mins Linux how-to Using the apropos command on Linux By Sandra Henry-Stocker Apr 24, 2024 3 mins Linux PODCASTS VIDEOS RESOURCES EVENTS NEWSLETTERS Newsletter Promo Module Test Description for newsletter promo module. Please enter a valid email address Subscribe