ikegami
ikegami

Reputation: 385789

sh: Test for existence of files

How does one test for the existence of files in a directory using bash?

if ... ; then
   echo 'Found some!'
fi

To be clear, I don't want to test for the existence of a specific file. I would like to test if a specific directory contains any files.


I went with:

(
   shopt -s dotglob nullglob
   existing_files=( ./* )
   if [[ ${#existing_files[@]} -gt 0 ]] ; then
      some_command "${existing_files[@]}"
   fi
)

Using the array avoids race conditions from reading the file list twice.

Upvotes: 8

Views: 14306

Answers (8)

user559633
user559633

Reputation:

I typically just use a cheap ls -A to see if there's a response.

Pseudo-maybe-correct-syntax-example-ahoy:

if [[ $(ls -A my_directory_path_variable ) ]] then....

edit, this will work:

myDir=(./*) if [ ${#myDir[@]} -gt 1 ]; then echo "there's something down here"; fi

Upvotes: 7

Vidul
Vidul

Reputation: 10538

# tested on Linux BASH

directory=$1

if test $(stat -c %h $directory) -gt 2;
then
   echo "not empty"
else
   echo "empty"
fi

Upvotes: 1

paxdiablo
paxdiablo

Reputation: 881453

You can use ls in an if statement thus:

if [[ "$(ls -a1 | egrep -v '^\.$|^\.\.$')" = "" ]] ; then echo empty ; fi

or, thanks to ikegami,

if [[ "$(ls -A)" = "" ]] ; then echo empty ; fi

or, even shorter:

if [[ -z "$(ls -A)" ]] ; then echo empty ; fi

These basically list all files in the current directory (including hidden ones) that are neither . nor ...

If that list is empty, then the directory is empty.

If you want to discount hidden files, you can simplify it to:

if [[ "$(ls)" = "" ]] ; then echo empty ; fi

A bash-only solution (no invoking external programs like ls or egrep) can be done as follows:

emp=Y; for i in *; do if [[ $i != "*" ]]; then emp=N; break; fi; done; echo $emp

It's not the prettiest code in the world, it simply sets emp to Y and then, for every real file, sets it to N and breaks from the for loop for efficiency. If there were zero files, it stays as Y.

Upvotes: 4

ikegami
ikegami

Reputation: 385789

For fun:

if ( shopt -s nullglob ; perl -e'exit !@ARGV' ./* ) ; then
   echo 'Found some!'
fi

(Doesn't check for hidden files)

Upvotes: 0

Keith Thompson
Keith Thompson

Reputation: 263267

I don't have a good pure sh/bash solution, but it's easy to do in Perl:

#!/usr/bin/perl

use strict;
use warnings;

die "Usage: $0 dir\n" if scalar @ARGV != 1 or not -d $ARGV[0];
opendir my $DIR, $ARGV[0] or die "$ARGV[0]: $!\n";
my @files = readdir $DIR;
closedir $DIR;
if (scalar @files == 2) { # . and ..
    exit 0;
}
else {
    exit 1;
}

Call it something like emptydir and put it somewhere in your $PATH, then:

if emptydir dir ; then
    echo "dir is empty"
else
    echo "dir is not empty"
fi

It dies with an error message if you give it no arguments, two or more arguments, or an argument that isn't a directory; it's easy enough to change if you prefer different behavior.

Upvotes: 1

Conrad Shultz
Conrad Shultz

Reputation: 8808

From the man page:

   -f file
          True if file exists and is a regular file.

So:

if [ -f someFileName ]; then echo 'Found some!'; fi

Edit: I see you already got the answer, but for completeness, you can use the info in Checking from shell script if a directory contains files - and lose the dotglob option if you want hidden files ignored.

Upvotes: 14

Xaxxon
Xaxxon

Reputation: 11

#!/bin/bash

if [ -e $1 ]; then
        echo "File exists"
else 
       echo "Files does not exist"
fi 

Upvotes: 1

Steve Robillard
Steve Robillard

Reputation: 13471

Try this

if [ -f /tmp/foo.txt ]
then
    echo the file exists
fi

ref: http://tldp.org/LDP/abs/html/fto.html

you may also want to check this out: http://tldp.org/LDP/abs/html/fto.html

How about this for whether directory is empty or not

$ find "/tmp" -type f -exec echo Found file {} \;

Upvotes: 3

Related Questions