Can you explain me usage of nullglob variable under BASH? How do I check for any *.c files in any directory?
BASH shell has the following two special variables to control pathname expansion. Bash scans each word for the characters *, ?, and [. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of file names matching the pattern.
a] nullglob : If set, bash allows patterns which match no files to expand to a null string, rather than themselves. This is useful to check for any *.mp3 or *.cpp files in directory.
b] dotglob If set, bash includes filenames beginning with a . in the results of pathname expansion.
How do I set and unset nullglob variable?
Use shopt command to toggle the values of variables. The -s option enable nullglob effects and the -u option disable nullglob option.
shopt -s nullglob # enable shopt -u nullglob # disable
Here is sample shell script to see if *.mp3 exists or not in a directory:
#!/bin/bash old=$(cd) [ $# -eq 0 ] && exit 1 [ -d $1 ] && cd $1 || exit 2 shopt -s nullglob found=0 for i in *.mp3; do echo "File $i found" # or take other action found=1 done shopt -u nullglob [ $found -eq 0 ] && echo "Directory is empty" cd $old
Without nullglob i will expand to *.mp3 only if there are no files in given directory. You can also use GNU find command to find out if directory is empty or not i.e. check for any *.c files in a directory called ~/project/editor:
find ~/project/editor -maxdepth 0 -empty -exec echo {} directory is empty. \;
Where,
- -maxdepth 0: Do not scan for sub directories.
- -empty : File is empty and is either a regular file or a directory.
- -exec echo {} directory is empty. \; : Display message if directory is empty.
🐧 6 comments so far... add one ↓
Category | List of Unix and Linux commands |
---|---|
File Management | cat |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Network Utilities | 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 • jobs • killall • kill • pidof • pstree • pwdx • time |
Searching | grep • whereis • which |
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 |
How do you know these things? Either you must have the memory of an elephant, or know how to use google in some magic way :)
One thing I don’t understand is why certain bash variables are stored with shopt and others with environment variables (like IFS). Historic reasons?
I’ve been using UNIX and Linux for over decade so I know lots of things. bash man page has all the info.
shopt use to toggle the values of variables controlling optional behavior. Usually it can be on or off only. On other hand, IFS value can be anything as per users requirements.
Great Lesson,
I was just introduced to this via Vivek. I am planning to use this feature in many ways.
Thanks,
Jaysunn
great explanation to make complicated things simple!
Nice example too.
Thank you very much
The for name in pattern construction is good for doing stuff to all matching files, but sometimes all that’s needed is a quick test for whether at least one matching file exists. The stat command can help with that:
if stat -t *.mp3 >/dev/null 2>&1
then
echo At least one file matching *.mp3 exists
else
echo No files match *.mp3
fi
This is portable to shells other than bash, many of which don’t support nullglob.
Mighty useful. Make no mistake, I aprpceiate it.