Sunday, May 27, 2012

How do I tell if a file does not exist in bash?


I've used the following script to see if a file exists:




#!/bin/bash
FILE=$1

if [ -f $FILE ];
then
echo "File $FILE exists."
else
echo "File $FILE does not exist."
fi



What's the correct syntax to use if I only want to check if the file does not exist?




#!/bin/bash
FILE=$1

if [ $FILE does not exist ];
then
echo "File $FILE does not exist."
fi


Source: Tips4all

9 comments:

  1. Bash has a "not" logical operator, which is the exclamation point (similar to many other languages). Try this:

    if [ ! -f /tmp/foo.txt ];
    then
    echo "File not found!"
    fi

    ReplyDelete
  2. You can negate an expression with "!":

    #!/bin/bash
    FILE=$1

    if [ ! -f $FILE ]
    then
    echo "File $FILE does not exists"
    fi


    The relevant manpage is "man test".

    ReplyDelete
  3. if [[ ! -a $FILE ]]; then
    echo "$FILE does not exist!"
    fi


    Also, it's possible that the file is a broken symbolic link. If you want to catch that you should:

    if [[ ! -a $FILE ]]; then
    if [[ -L $FILE ]]; then
    echo "$FILE is a broken symlink!"
    else
    echo "$FILE does not exist!"
    fi
    fi

    ReplyDelete
  4. I've found this list of bash conditional statements very useful.

    ReplyDelete
  5. If you type "man test" it will show you all the syntax for the "[ ]" (test) in bash.

    ReplyDelete
  6. It's worth mentioning that if you need to execute a single command you can abbreviate

    if [ ! -f $file ]; do echo $file;fi


    to

    test -f $file || echo $file

    ReplyDelete
  7. You should be careful about running test for unquoted variable, because it might produce unexpected results:

    $ [ -f ]
    $ echo $?
    0
    $ [ -f "" ]
    $ echo $?
    1


    The recommendation is usually to have the tested variable surrounded by double quotation marks:

    #!/bin/bash
    FILE=$1

    if [ ! -f "$FILE" ];
    then
    echo "File $FILE does not exist."
    fi

    ReplyDelete
  8. Keep in mind, I'm only considering Bash. This is how I prefer to do a one liner, I actually use this syntax even for a couple commands.

    # [ /$DIR/$FILE ] || echo "$FILE NOT FOUND"

    # [ /$DIR/$FILE ] && echo "$FILE FOUND"


    For a couple commands, like I would do in a script.

    # [ /$DIR/$FILE ] || { echo "$FILE NOT FOUND" ; exit 1 ;}


    Once I started doing this, rarely use the fully typed syntax!!

    ReplyDelete
  9. you can use -z , eg

    if [ -z `which grep` ] ;then echo "Missing grep"; fi

    ReplyDelete