- How To Check If a Directory Exists In a Shell Script
- Checking If a Directory Exists In a Bash Shell Script
- Using if..else..if
- Shell script examples to see if a $ exists or not
- Summary
- Conclusion
- Check if a directory exists in Linux or Unix shell
- How to check if a directory exists in Linux
- A note about symbolic links (symlink)
- Linux check if a directory exists and take some action
- Check if directory exists in bash and if not create it
- Using test command
- Getting help
- Conclusion
- Bash Shell Check Whether a Directory is Empty or Not
- Check whether a directory is empty or not using find command
- Bash scripting – Test for empty directory and files
- Check if folder /data/ is empty or not using bash only features
- A note about ksh user
How To Check If a Directory Exists In a Shell Script
Tutorial details | |
---|---|
Difficulty level | Easy |
Root privileges | No |
Requirements | Bash/Linux |
Est. reading time | 3 mintues |
Checking If a Directory Exists In a Bash Shell Script
The following version also check for symbolic link:
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
The && is AND list operator. The syntax is:
foo && bar
The bar command is executed if, and only if, foo returns an exit status of zero (success). Similarly we have the || (OR) list and the syntax is:
cmd1 || cmd2
The cmd2 is executed if, and only if, cmd1 returns a non-zero exit status. The return status of AND and OR lists is the exit status of the last command executed in the list.
Using if..else..if
Finally, you can use the traditional if..else..fi bash syntax as follows:
Shell script examples to see if a $ exists or not
The following script also demos the use of readlink command to print value of a symbolic link or canonical file name.
Save and run it as follows:
$ chmod +x dirtest.bash
$ ./dirtest.bash
$ ./dirtest.bash /home/httpd
$ ./dirtest.bash /var/www
Sample outputs:
Fig.01: Shell script in action
Summary
Remember when we say “FILE”, it means directory too.
Use the following to check file/directory types and compare values:
- -L «FILE» : FILE exists and is a symbolic link (same as -h)
- -h «FILE» : FILE exists and is a symbolic link (same as -L)
- -d «FILE» : FILE exists and is a directory
- -w «FILE» : FILE exists and write permission is granted
- -x «FILE» : FILE exists and execute (or search) permission is granted
- -r «FILE» : FILE exists and read permission is granted
- -s «FILE» : FILE exists and has a size greater than zero
Conclusion
We learned how to check if a directory exists in a shell script using the test command and other methods under Linux/Unix bash. See the following resources for more information:
man test
man bash
man readlink
man stat
And:
🐧 Get the latest tutorials on Linux, Open Source & DevOps via
Category | List of Unix and Linux commands |
---|---|
Documentation | help • mandb • man • pinfo |
Disk space analyzers | df • duf • ncdu • pydf |
File Management | cat • cp • less • mkdir • more • tree |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Linux Desktop Apps | Skype • Spotify • VLC 3 |
Modern utilities | bat • exa |
Network Utilities | NetHogs • dig • host • ip • nmap |
OpenVPN | CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04 |
Package Manager | apk • apt |
Processes Management | bg • chroot • cron • disown • fg • glances • gtop • jobs • killall • kill • pidof • pstree • pwdx • time • vtop |
Searching | ag • grep • whereis • which |
Shell builtins | compgen • echo • printf |
Text processing | cut • rev |
User Information | groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w |
WireGuard VPN | Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04 |
Comments on this entry are closed.
I sometime use “[ -x $dir/. ]”, to check at the same time if directory exist and if the calling process has traverse rights on it.
“exits” “exits” “exits” all over the place where you had intended to write “exists”. you might want to change that.
Thanks for the heads up!
i love this one:
[[ -d dir ]] || mkdir dir
Isn’t that same as `mkdir -p dir`?
I really like this one for setting a variable to a file path only if it exists. From what I can tell, this is probably amongst the most efficient methods of doing such a task.
Lets assume we have the following:
/path/to/file
Using bash’s builtin “type” the “-P” does a PATH search, only printing if the filename is found within the path, irrespective of the executable state:
$ VAR1=$(PATH=/path/to type -P file)
$ echo $VAR1
/path/to/file
$
What is really neat about this is that we can use it to see if the file exists in several places, using the order of the temporary PATH to indicate preferences.
Let’s add a couple files for an example:
/path/to/file
/path/to/other/file
/other/directory/foo
Now if we want to set “file” as a variable, and know it should be in one of three places, we can do…
$ VAR2=$(PATH=/path/to/other:/path/to:/other/directory type -P file)
$ echo $VAR2
/path/to/other/file
$
But what if /path/to takes precedence? An example is any program that gives configs in /etc priority over /usr/lib if identically named (ie. systemd, modprobe.d, etc.). We can use the PATH order to match by level of significance…
$ VAR3=$(PATH=/path/to:/path/to/other:/other/directory type -P file)
$ echo $VAR3
/path/to/file
$
Bash’s builtin “type” is quite nice in that upon failure, it prints nothing. So you don’t even need to throw out stderr with “2>/dev/null”!
$ VAR4=$(/path/to:/path/to/other:/other/directory type -P baz)
$ echo $VAR4
Even if you did “echo $FARTBRAINS” it still creates a nice \n for you, even if you’ve never even remotely thought about using that variable name. So VAR4 is essentially unset. Neat!
Usually I’m a zsh user. Zsh’s “whence” and “which” come closest, but cannot search beyond executables and print a short fail message (that I’d otherwise not mind). I’m sure other shells might behave similarly, but those are the two I’ve tested. I script with bash anyway.
Unfortunately, I have not come up with a way to do directories in a similar manner. I really searched through the bash shell builtin documentation and google-fu’ed the best I could, but I cannot figure anything out that is that efficient.
Hopefully someone smarter than me can prove there is a way. I don’t know if I’ll ever check this page again… and don’t know why I just put so much work into this comment. But I hope you enjoyed!
Hi, there is an error in your example, if the dir does not exist at all (and no link) the example below still prints the “Error……” (the OR part)
Yep, I concur, it’s incorrect/incomplete in that sense. I’ve made a quick alteration that I believe works with a bit more clarity:
Slight improvement for stdin / stdout clarity:
[ -d «$aptLocalRepo» ] && [ ! -L «$aptLocalRepo» ] && printf «Dir:\nDirectory exists: $aptLocalRepo\n» || \
[ -L $aptLocalRepo ] && printf «Symlink:\n$aptLocalRepo\nPoints to:\n$(readlink -f $aptLocalRepo)\n» || \
printf «Dir:\nDirectory does not exist: $aptLocalRepo\n»
Second example is a typo – you need a space between the opening bracket and the bang, like this
The current code would cause “ bash: [!: command not found ” error message
Источник
Check if a directory exists in Linux or Unix shell
How to check if a directory exists in Linux
- One can check if a directory exists in a Linux shell script using the following syntax:
[ -d «/path/dir/» ] && echo «Directory /path/dir/ exists.» - You can use ! to check if a directory does not exists on Unix:
[ ! -d «/dir1/» ] && echo «Directory /dir1/ DOES NOT exists.»
One can check if a directory exists in Linux script as follows:
Always enclose “$DIR” in double-quotes to deal with directories having white/black spaces in their names. For instance:
A note about symbolic links (symlink)
Directories with symbolic links need special consideration as follows using the -L switch:
Linux check if a directory exists and take some action
Here is a sample shell script to see if a folder exists or not in Linux:
Run it as follows:
./test.sh
./test.sh /tmp/
./test.sh /nixCraft
Check if directory exists in bash and if not create it
Here is a sample shell script to check if a directory doesn’t exist and create it as per our needs:
Make sure you always wrap shell variables such as $DIR in double quotes ( «$DIR» to avoid any surprises in your shell scripts:
Using test command
One can use the test command to check file types and compare values. For example, see if FILE exists and is a directory. The syntax is:
test -d «DIRECTORY» && echo «Found/Exists» || echo «Does not exist»
The test command is same as [ conditional expression. Hence, you can use the following syntax too:
[ -d «DIR» ] && echo «yes» || echo «noop»
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
Getting help
Read bash shell man page by typing the following man command or visit online here:
man bash
help [
help [[
man test
Conclusion
This page explained various commands that can be used to check if a directory exists or not, within a shell script running on Linux or Unix-like systems. The -d DIR1 option returns true if DIR1 exists and is a directory. Similarly, the -L DIR1 option returns true if DIR1 found and is a symbolic links.
🐧 Get the latest tutorials on Linux, Open Source & DevOps via
Источник
Bash Shell Check Whether a Directory is Empty or Not
H ow do I check whether a directory is empty or not under Linux / UNIX using a shell script? I would like to take some action if directory is empty on a Linux or Unix like system. How can I check from bash/ksh shell script if a directory contains files? How do I check whether a directory is empty or not?
There are many ways to find out if a directory is empty or not under Linux and Unix bash shell. You can use the find command to list only files.
Tutorial details | |
---|---|
Difficulty level | Easy |
Root privileges | No |
Requirements | None |
Est. reading time | 3 mintues |
In this example, find command will only print file name from /tmp. If there is no output, directory is empty.
Check whether a directory is empty or not using find command
The basic syntax is as follows:
The -empty test if given file is empty and is either a regular file or a directory. For example:
$ mkdir /tmp/demo
$ find /tmp/demo -maxdepth 0 -empty -exec echo <> is empty. \;
/tmp/demo is empty.
$ touch /tmp/demo/file.txt
$ ls -l /tmp/demo/file.txt
$ find /tmp/demo -maxdepth 0 -empty -exec echo <> is empty. \;
In this example, check whether a directory called /tmp/ is empty or not, type:
$ find «/tmp» -type f -exec echo Found file <> \;
Sample outputs:
However, the simplest and most effective way is to use ls command with -A option:
$ [ «$(ls -A /path/to/directory)» ] && echo «Not Empty» || echo «Empty»
or
$ [ «$(ls -A /tmp)» ] && echo «Not Empty» || echo «Empty»
You can use if..else.fi in a shell script:
Run it as follows:
./script /tmp
./script /tmp/foobar
mkdir /tmp/foobar
./script /tmp/foobar
touch /tmp/foobar/filename
./script /tmp/foobar
Bash scripting – Test for empty directory and files
Here is another example using bash for loop to check for any *.c files in the
Check if folder /data/ is empty or not using bash only features
From the Linux and Unix bash(1) man page:
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
- nullglob If set, bash allows patterns which match no files to expand to a null string, rather than themselves.
- dotglob – If set, bash includes filenames beginning with a . in the results of pathname expansion.
A note about ksh user
Try for loop as follows:
🐧 Get the latest tutorials on Linux, Open Source & DevOps via
Category | List of Unix and Linux commands |
---|---|
Documentation | help • mandb • man • pinfo |
Disk space analyzers | df • duf • ncdu • pydf |
File Management | cat • cp • less • mkdir • more • tree |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Linux Desktop Apps | Skype • Spotify • VLC 3 |
Modern utilities | bat • exa |
Network Utilities | NetHogs • dig • host • ip • nmap |
OpenVPN | CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04 |
Package Manager | apk • apt |
Processes Management | bg • chroot • cron • disown • fg • glances • gtop • jobs • killall • kill • pidof • pstree • pwdx • time • vtop |
Searching | ag • grep • whereis • which |
Shell builtins | compgen • echo • printf |
Text processing | cut • rev |
User Information | groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w |
WireGuard VPN | Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04 |
Comments on this entry are closed.
Seems to me that using ls is not required – in fact, it is doable within the shell alone:
set — `echo .* *`
if [ $# = «2» ] ; then
: empty directory
else
: not empty .
fi
It is not working for me. I’m using Debian + Bash 3. It returns 3 when directory is empty, it should be 2 as empty directory has only . and ..
Yes. I’d forgotten: when no matches are found (“*”) then the resulting text is the character unchanged. This should work better:
FILES=”`echo .* *`”
if [ $FILES = ‘. .. *’ ] ; then
: empty dir
else
: not empty
fi
find -type d -empty
`find . -depth -type d -empty` would work a little better..
EG:
Scot’s suggestion works absolutely perfectly.
A slight variation on the original post which does it numerically and includes dot files.
That’s a one and not an ‘l’ to the ls command. An empty directory only has the two entries – . & ..
Works with both BSD and GNU Linux find:
find «/nas/data» -maxdepth 0 -empty -exec echo <> is empty. \;
OR
find «/dir2» type d -empty -exec command1 -arg1 <> \;
I am trying to pass a directory path as a parameter to my bash script (which tests whether its empty), but the directory name contains spaces. Any suggestions?
enclose the directory name parameter in double quotes.
The following code does not correctly identify empty directories. Using DIR=$1 then passing “home/dan/not empty” does not help, neither does using “home/dan/not\ empty” or home/dan/not\ empty.
DIR=”home/dan/not empty”
if [ “$(ls -A $DIR)” ]; then
echo “$DIR is not empty”
else
echo “$DIR is empty”
fi
if [ “$(ls -A $DIR)” ]; then
if [ “$(ls -A “$DIR”)” ]; then
That’s just another pair of quotes, no escapes. Should work.
dude. give find some love 😉
find . -type d -empty -exec touch <>/.empty \;
find «/dir2» -type d -empty -exec command1 -arg1 <> \;
if [ «$(ls -A $DIR)» ]; then
How can I use this expression exclude one directory?
what if the directory has files but each file is of 0 size?
best way is to do as below:
This snippet assumes that a directory size, by its own name, is always 4096 bytes, approximated to 4.0K evaluated to int as 4
Hi all,
someone please say me why this dont work.
Declare the variable ,before you use it.
Ok, this works, after hours of coding a simple solution was found to be best loll.What kept giving me trouble was the *, also I had found a solution a long time ago, but it didnt work if you had empty files in the directory.I tried all the IF statement solutions and it wont work in all situations.So best method is below:
for i in $DIR/*
do
if [ -e $i ] && [ $(echo $?) -eq “0 ” ]
then
echo The Directory is NOT EMPTY
echo The directory is EMPTY
Very good Vivek. Cool.
if [ $( stat -c %h . ) -gt 2 ] ; then echo not empty; fi
Solution with “$(ls -A $DIR)” could exceed command buffer size.
Square brackets are only needed with if when you’re using test expressions, and by doing away with them you can do away with the process substitution. You can test the exit status of a program or command just by running it. (Getting ls to give an error code in this case requires a slight change in syntax.)
If used in a script, I’d go with a slight modification of the first comment (as the “set” clobbers positional parameters, putting it in a function will clobber only local function parameters, not the global ones!):
And then calling:
why not using simple :
if [ ! -f /folder/* ]; then
echo “folder not empty”
else
echo “folder empty”
fi
I had a seriously nasty time with this.
In a bash script I wanted to:
1. Create and pass a list of directories that match a pattern
2. Use a variable to check if the directories matching the pattern were empty
3. Delete empty directories.
The challenge I ran into was with wildcard expansion in variables. I spent a little while pulling my hair out over ” and ‘ and ` until I figured out (the final solution was pretty simple).
Here is my short script that
1. creates a list of directories within $1 that match a pattern
– in this case the grep returns all directories that are 5 numerical digits
2. verifies whether or not content exists
3. deletes the directory if no content is present
#!/bin/bash
# List Empty Directories that are directories in the
# format ./##### If they are empty, delete them.
ls -d */ > testdir.txt
grep ‘8\<5\>’ ./testdir.txt > testdir2.txt
rm ./testdir.txt
while [ $i -le `wc -l ./testdir2.txt | gawk ‘
line=`head -$i ./testdir2.txt | tail -1`
correctdirname=”./”$line
echo -n “Dir “$i” “$correctdirname
files=`echo $correctdirname $correctdirname*`
test=$correctdirname” “$correctdirname”*”
if [ “$files” == “$test” ]
then echo ” empty” #; rm -rf $correctdirname
else echo ” files found”
fi
For safety I commented out the delete/rm. Anyone trying this should test carefully before running this script and use a test directory with test data. The delete command will delete entire directories whether they are empty or not! Verify your scenario, verify the variables match your scenario, and double-check before uncommenting that rm command.
I hope someone finds this useful.
I mistakenly said “1. creates a list of directories within $1 that match a pattern”
It should read “1. creates a list of directories within the current directory that match a pattern”
Also I didn’t remove testdir2.txt, created by the script in the current directory. A line to remove that could be added after the “done” to clean up the 2nd temporary file created by the script.
After having solved the logic problem I was overly-focused on I was playing around with additional information from the above posts and changed my if statment based upon the one provided by nixcraft, above:
My if original: if [ “$files” == “$test” ]
Nixcraft’s if: if [ “$(ls -A $DIR)” ]
My new if: if [ ! “$(ls -A $line)” ]
Using the if provided by Nixcraft I came up with an if that works in place of the if statement in my above script and is a little cleaner because it does not require creation of the $test variable. I put a ! in front of it so I could easily swap if statements. Alternately you could reverse the then-else.
Here is the updated script with the old vars and if commented out:
#!/bin/bash
# List Empty Directories that are directories in the
# format ./##### If they are empty, delete them.
ls -d */ > testdir.txt
grep ‘1\<5\>’ ./testdir.txt > testdir2.txt
rm ./testdir.txt
while [ $i -le `wc -l ./testdir2.txt | gawk ‘
line=`head -$i ./testdir2.txt | tail -1`
correctdirname=”./”$line
echo -n “Dir “$i” “$correctdirname
# files=`echo $correctdirname $correctdirname*`
# test=$correctdirname” “$correctdirname”*”
# if [ “$files” == “$test” ]
if [ ! “$(ls -A $line)” ]
then echo ” empty” #; rm -rf $correctdirname
else echo ” files found”
fi
Note I added the final line to remove the 2nd test/data file.
Also you should be able to comment out the if and uncomment the 3 lines above it to switch back and forth between the two options.
This is why I don’t post often. I keep finding mistakes. I don’t know how other posters do it–such simple elegant posts that are correct.
Upon further inspection I realized my if statement, while it works in my bash, is using the wrong variable. I created the $correctdirname variable because grepping directories gave me ##### rather than ./#####.
if [ ! “$(ls -A $line)” ]
I believe you should be using $correctdirname for the reason above even though the script works for me–I don’t know if it will work generically given the difference.
The “more-correct” if-statement:
if [ ! “$(ls -A $correctdirname)” ]
if [ ! “$(ls -A “$FOLDER”)” ]; then
echo “$FOLDER is empty”
fi
When searching for methods to automatically mount virtualbox shared folders,
reliable and correct methods are hard to distinguish from those that fail.
Failures include getting and setting permissions, as well as other problems.
Methods that fail include:
modifying /etc/fstab
modifying /etc/rc.local
I am fairly certain that rc.local can be used,
but no methods I have tried worked.
I welcome improvements on these guidelines.
On virtualbox 4.2.14 running nautilus (bash terminal) on an ubuntu 13.04 guest,
Below is a working method to mount Common (sharename)
on /home/$USER/Desktop/Common (mountpoint) with full permissions.
(Note the ‘\’ command continuation character in the find command.)
First time only: create your mountpoint, modify your .bashrc file, and run it.
Respond with password when requested.
These are the four command-lines needed.
mkdir $HOME/Desktop/Common
sudo echo “$USER ALL=(ALL) NOPASSWD:ALL” >> /etc/sudoers
find $HOME/Desktop/Common -maxdepth 0 -type d -empty -exec sudo \
mount -t vboxsf -o \
uid=`id -u $USER`,gid=`id -g $USER` Common $HOME/Desktop/Common \;
source
/.bashrc # Needed if you want to mount Common in this bash.
All other times: simply launch a bash shell.
The find command detects an empty mountpoint directory.
If the Common directory is not empty, it does not run the mount command.
I hope this is error-free and sufficiently general.
Please let me know of corrections and improvements.
How to make two directories “C_ Programming ” and “Shell Script” ?
A)Create a text file “Pros_and_Cons_of_C.txt” in “C_programming” directory
B)Create a text file “Pros_and_Cons_of_C.txt” in “Shell_Script” directory
C)Write a suitable pros and cons for each text file in your own words using keyboards inputs.
Write a shell script to create a directory “Shell2” Create 10 text files “a5_1.txt” “a5_10.txt” using loop inside the directory “Shell2.” Give access privilege for those text files , read only for others and group , read and write for owner..
Please help me for above all forums that i sent. those are may be primary level questions , but i can’t understand for answer those questions. please help me for do my university assignment..
That’s great for you, learning Linux computer science, and this means first: learn. Nobody can do it for you.
Fortunately, somebody has built and offered to all a great resource to learn, which is also a cooperative work:
http://bash.cyberciti.biz/guide/Main_Page
I could have added, among other resources:
Not a better solution, but this also works:
Please remove/disregard my previous comment, this is what I meant. Checks for just one folder (current one) and it’s size being 4096 bytes.
rm -rf “%*”
mkdir “%*”
echo NOW it’s empty.
exit 0
Thanks for this post! I have a comment and a potential method.
Method: Why wouldn’t this work?
ls $DIR/*
echo $? # a ‘1’ would mean the directory is empty
Comment: As far as I can tell, this version, the find command version, and ls -A, will not detect a directory that contains subdirectories but is void of files. I am perplexed that the below does not work. Assume $DIR has a single subdirectory, foo, and neither have regular files:
find $DIR -type f -exec echo $DIR is empty \;
PS I did find for my ancillary problem (may contain subdirectories but no files) this solution:
let “$m = `find $DIR -type f | wc -l`” ; test $m = 0 ; echo $?
Also, a nit in my original suggestion: adjust the ls command so you don’t get unwanted output:
ls $DIR/* > /dev/null
echo $? # a ’1′ would mean the directory is empty
if [ “$(ls -A $DIR)” ]; then
echo “Take action $DIR is not Empty”
else
echo “$DIR is Empty”
fi
could be written a bit simpler without backquote substitution:
if ls -A $DIR >/dev/null
then
echo Take action ….
else
echo $Dir is empty
fi
NO, this is not true. Your check
checks for the EXIT value of “ls”, which is 0 if directory $DIR exists (even if it is empty),
while
[ “$(ls -A $DIR)” ] checks whether the OUTPUT of “ls” is non-empty, i.e. the directory is non-empty. See the man page test(1).
Thank you, VVS. Worked like a charm for a novice.
Источник