How do I use a Bash check to detect only when a file is missing?

I know how to use the standard bash check if file exists approach like this:

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

But I want to simplify the condition to only run something if the file does not exist, without using an else block. What’s the cleanest way in Bash to detect that a file is missing and act only in that case?

Over the years, I’ve found one clean approach to be using the ! operator directly in the if statement to check if a file is missing. It keeps your intent clear—you’re saying directly ‘if the file does not exist.’ It looks like this:

if [ ! -f "$FILE" ]; then
  echo "File is missing. Taking action..."
fi

This way, you avoid the need for an else block, and it reads naturally, making the script much easier to revisit later. It’s straightforward and effective, especially when you don’t need to do anything else if the file exists.

I totally agree with @macy-davis, but here’s another way to make things even more concise. If you’re working on shorter scripts or in-line checks, you can combine the logic into a one-liner using the && operator. This makes your script more compact and executes only when the file is missing. Here’s how:

[ ! -f "$FILE" ] && echo "File is missing, handling it..."

This avoids traditional if blocks entirely, and it’s fantastic for quick automation hooks or cron jobs where you just need to take action when the file is absent. It’s clean and efficient, plus it keeps things running smoothly without the need for extra conditional structures.

Great points, @macy-davis and @yanisleidi-rodriguez!

If you’re aiming for portability and want to safeguard against any potential issues (like when $FILE is empty or unset), I’d recommend wrapping it in double brackets with the ! operator. It ensures that you avoid weird behavior with special characters or undefined variables. It looks like this:


if [[ ! -f "$FILE" ]]; then
  echo "Missing file detected."
fi

Using double brackets in this way adds a level of robustness to your script. It’s a small change but goes a long way in preventing those silent failures when a variable unexpectedly comes up empty. I’ve made this my go-to style for more defensive scripting, especially when reliability is key.