MDLog:/sysadmin

The Journal Of A Linux Sysadmin

Bash Tips: If -e Wildcard File Check => [: Too Many Arguments

| Comments

Here is a quick bash tip that might be useful if you need to use inside a bash script a check to see if a wildcard expression of files/folders exists or not. For example:

1
2
3
4
5
6
if [ -e /tmp/*.cache ]
then
echo "Cache files exist: do something with them"
else
echo "No cache files..."
fi

This is using -e (existing file check) that is working fine on individual files. Also the above code might seem to work fine if the result of the expression if one file; but if you have more files returned by the expression this will fail with the following error:

1
line x: [: too many arguments

This is unfortunately normal as ‘-e’ can take only one parameter, so it will not work with multiple results. This means we have to find a walkaround for this issue… There are probably many solutions for this problem; my¬† idea is to run ls and count the results and then feed that to if. Something like:

1
2
3
4
5
6
7
files=$(ls /tmp/*.cache)
if [ $files ]
then
echo "Cache files exist: do something with them"
else
echo "No cache files..."
fi

Now this is obviously wrong as if there are no files in the directory we will get a result like this:

1
ls: cannot access /tmp/*.cache: No such file or directory

and we don’t want to count that. We need to ignore such errors when files are not there, and we will use:

1
files=$(ls /tmp/*.cache **2> /dev/null**)

this way ls errors printed to STDERR now go to /dev/null and we don’t have to worry about them anymore.

This is still not good enough, as if will feed it with more values than it will still fail (when we have more files):

1
line x: [: /tmp/1.cache: unary operator expected

Obviously the proper way to do this would be to count the number of files and for this we just add ”wc -l” to count the result of ls. This should look like this:

1
2
3
4
5
6
7
files=$(ls /tmp/*.cache 2> /dev/null | wc -l)
if [ **"$files" != "0"** ]
then
echo "Cache files exist: do something with them"
else
echo "No cache files..."
fi

and if needed we can even use the $files variable that now has the number of file. I hope you will find this useful if you need to do something similar; obviously the file check was just an example, and you would use this based on your needs and inside a script that does something useful ;-) .

Comments