Linux bash if find file

3 ways to check if file exists in bash

In this blog post, we will discuss 3 different ways to check if a file exists in Bash. This is an important skill to have when you are working with files in a Linux environment. Each of these methods has its own benefits and drawbacks, so it is important to understand them all before deciding which one to use. Let’s get started!

The following Linux commands can be used to check if a file exists in bash.

  • test -f /path/to/file && echo “FILE exists.” || echo “File does not exist”
  • [ -e /path/to/file ] && echo “FILE exists.” || echo “File does not exist”
  • [ -f /path/to/file ] && echo “FILE exists.” || echo “File does not exist”

Check if a File Exists Using the test Command in bash

The first method we will discuss is using the test command. This is a built-in command in Bash that can be used to test various things. In this case, we are interested in using it to check if a file exists. The syntax for this command is as follows:

If the file exists, this command will return a 0 exit code. If the file does not exist, it will return a non-zero exit code. So, we can use this command to check if a file exists like so:

if test -e /path/to/file; then
echo “File exists”
else
echo “File does not exist”
fi

We can do this in one command like this.
test -e /path/to/file && echo “FILE exists.” || echo “File does not exist”

Check if a File Exists Using if statement -e option in bash

The best Linux command to check if a file Exists in bash is using the if statement -e option. The -e option is a built-in operator in Bash to check file exists. If the file exists, this command will return a 0 exit code. If the file does not exist, it will return a non-zero exit code.

The syntax for this operator is as follows:

if [ -e /path/to/file ] ; then
echo “File exists”
else
echo “File does not exist”
fi

We can do this in one command.

[ -e /path/to/file ] && echo “FILE exists.” || echo “File does not exist”

Check if a File Exists Using -f option in bash if statement

The third method we will discuss is using the -f option in if statement. The -e option checks if the file path exists, while the -f option checks if the file path exists and if it is a regular file. The syntax for these operators are as follows:

if [-f /path/to/file ] ; then
echo “File exists”
else
echo “File does not exist”
fi

we can do this in one command line.
[ -f /path/to/file ] && echo “FILE exists.” || echo “File does not exist”

File test operators in bash

The test command includes the following FILE operators that allow you to test for particular types of files:

  • -d FILE FILE exists and is a directory.
  • -e FILE FILE exists.
  • -r FILE FILE exists and the read permission is granted.
  • -s FILE FILE exists and it’s size is greater than zero (ie. it is not empty).
  • -w FILE FILE exists and the write permission is granted.
  • -x FILE FILE exists and the execute permission is granted.
Читайте также:  Linux сделать загрузочный iso

As you can see, there are many different ways to check if a file exists in Bash. Each of these methods has its own benefits and drawbacks, so it is important to understand them all before deciding which one to use. In general, the “test” command is the simplest and most reliable way to check if a file exists. However, the other methods can be useful in certain situations. Thanks for reading!

David is a Cloud & DevOps Enthusiast. He has years of experience as a Linux engineer. He had working experience in AMD, EMC. He likes Linux, Python, bash, and more. He is a technical blogger and a Software Engineer. He enjoys sharing his learning and contributing to open-source.

howtouselinux.com is dedicated to providing comprehensive information on using Linux.

We hope you find our site helpful and informative.

Источник

How can I use bash’s if test and find commands together?

I have a directory with crash logs, and I’d like to use a conditional statement in a bash script based on a find command. The log files are stored in this format:

/var/log/crashes/app-2012-08-28.log /var/log/crashes/otherapp-2012-08-28.log 

I want the if statement to only return true if there is a crash log for a specific app which has been modified in the last 5 minutes. The find command that I would use is:

find /var/log/crashes -name app-\*\.log -mmin -5 
if [ test `find /var/log/crashes -name app-\*\.log -mmin -5` ] then service myapp restart fi 
  • I’ve looked at the if flags but I’m not sure which one, if any, that I should use.
  • Do I need the test directive or should I just process against the results of the find command directly, or maybe use find. | wc -l to get a line count instead?
  • Not 100% necessary to answer this question, but test is for testing against return codes that commands return? And they are sort of invisible — outside of stdout / stderr ? I read the man page but I’m still pretty unclear about when to use test and how to debug it.

The real answer to the general case is to use find . -exec . Also see the example commands under Why is looping over find’s output bad practice?

@Wildcard — unfortunately that doesn’t solve the general case: it doesn’t work if there is more than one match and the action needs to only run once, and it doesn’t work if you need an action to run when there are no matches. The former can be solved by using . -exec command ‘;’ -quit , but I don’t believe there is any solution for the latter other than parsing the result. Also, in either case, the primary problem with parsing the result of find (i.e. inability to distinguish delimiters from characters in filenames) doesn’t apply, as you don’t need to find delimiters in these cases.

-exec is good for quick response, but for wider conditions if find . | grep . is better: unix.stackexchange.com/a/684153/43233

7 Answers 7

[ and test are synonyms (except [ requires ] ), so you don’t want to use [ test :

[ -x /bin/cat ] && echo 'cat is executable' test -x /bin/cat && echo 'cat is executable' 

test returns a zero exit status if the condition is true, otherwise nonzero. This can actually be replaced by any program to check its exit status, where 0 indicates success and non-zero indicates failure:

# echoes "command succeeded" because echo rarely fails if /bin/echo hi; then echo 'command succeeded'; else echo 'command failed'; fi # echoes "command failed" because rmdir requires an argument if /bin/rmdir; then echo 'command succeeded'; else echo 'command failed'; fi 

However, all of the above examples only test against the program’s exit status, and ignore the program’s output.

Читайте также:  Обновить драйвера кали линукс

For find , you will need to test if any output was generated. -n tests for a non-empty string:

if [[ -n $(find /var/log/crashes -name "app-*.log" -mmin -5) ]] then service myapp restart fi 

A full list of test arguments is available by invoking help test at the bash commandline.

If you are using bash (and not sh ), you can use [[ condition ]] , which behaves more predictably when there are spaces or other special cases in your condition. Otherwise it is generally the same as using [ condition ] . I’ve used [[ condition ]] in this example, as I do whenever possible.

I also changed `command` to $(command) , which also generally behaves similarly, but is nicer with nested commands.

This answer beats all around the root of the problem but gracefully avoids mentioning exactly what that is.

find will exit successfully if there weren’t any errors, so you can’t count on its exit status to know whether it found any file. But, as you said, you can count how many files it found and test that number.

It would be something like this:

if [ $(find /var/log/crashes -name 'app-*.log' -mmin -5 | wc -l) -gt 0 ]; then . fi 

test (aka [ ) doesn’t check the error codes of the commands, it has a special syntax to do tests, and then exits with an error code of 0 if the test was successful, or 1 otherwise. It is if the one that checks the error code of the command you pass to it, and executes its body based on it.

See man test (or help test , if you use bash ), and help if (ditto).

In this case, wc -l will output a number. We use test ‘s option -gt to test if that number is greater than 0 . If it is, test (or [ ) will return with exit code 0 . if will interpret that exit code as success, and it will run the code inside its body.

if [ -n "$(find /var/log/crashes -name app-\*\.log -mmin -5)" ]; then 
if test -n "$(find /var/log/crashes -name app-\*\.log -mmin -5)"; then 

The commands test and [ … ] are exactly synonymous. The only difference is their name, and the fact that [ requires a closing ] as its last argument. As always, use double quotes around the command substitution, otherwise the output of the find command will be broken into words, and here you’ll get a syntax error if there is more than one matching file (and when there are no arguments, [ -n ] is true, whereas you want [ -n «» ] which is false).

In ksh, bash and zsh but not in ash, you can also use [[ … ]] which has different parsing rules: [ is an ordinary command, whereas [[ … ]] is a different parsing construct. You don’t need double quotes inside [[ … ]] (though they don’t hurt). You still need the ; after the command.

if [[ -n $(find /var/log/crashes -name app-\*\.log -mmin -5) ]]; then 

This can potentially be inefficient: if there are many files in /var/log/crashes , find will explore them all. You should make find stop as soon as it finds a match, or soon after. With GNU find (non-embedded Linux, Cygwin), use the -quit primary.

if [ -n "$(find /var/log/crashes -name app-\*\.log -mmin -5 -print -quit)" ]; then 

With other systems, pipe find into head to at least quit soon after the first match (find will die of a broken pipe).

if [ -n "$(find /var/log/crashes -name app-\*\.log -mmin -5 -print | head -n 1)" ]; then 

(You can use head -c 1 if your head command supports it.)

crash_files=(/var/log/crashes/**/app-*.log(mm-5[1])) if (($#crash_files)); then 

Источник

Читайте также:  Arch linux 32 bit install

How to check if find command didn’t find anything?

found something or not. If not I want to say echo ‘You don’t have files older than $DAYS days’ or something like this 😉 How I can do that in shell script?

6 Answers 6

Count the number of lines output and store it in a variable, then test it:

lines=$(find . | wc -l) if [ $lines -eq 0 ]; then . fi 

To use the find command inside an if condition, you can try this one liner :

 [[ ! -z `find 'YOUR_DIR/' -name 'something'` ]] && echo "found" || echo "not found" 
 [prompt] $ mkdir -p Dir/dir1 Dir/dir2/ Dir/dir3 [prompt] $ ls Dir/ dir1 dir2 dir3 [prompt] $ [[ ! -z `find 'Dir/' -name 'something'` ]] && echo "found" || echo "not found" not found [prompt] $ touch Dir/dir3/something [prompt] $ [[ ! -z `find 'Dir/' -name 'something'` ]] && echo "found" || echo "not found" found 

Alternatively, -n can be used instead of ! -z , for example:

[[ -n `find $dir -name $filename` ]] && echo found 
-n STRING the length of STRING is nonzero 

Exit 0 is easy with find, exit >0 is harder because that usually only happens with an error. However we can make it happen:

if find -type f -exec false <> + then echo 'nothing found' else echo 'something found' fi 

This is not correct. The question asks how to return false if it DOES NOT find anything. -exec will only run if it does find something so this would never work properly.

@deltaray: This answer returns false when files are found and true when they’re not. Simply negate the result with a ! or use the then/else as shown which is set up in a negated form.

I wanted to do this in a single line if possible, but couldn’t see a way to get find to change its exit code without causing an error.

However, with your specific requirement, the following should work:

find /directory/whatever -name '*.tar.gz' -mtime +$DAYS | grep 'tar.gz' || echo "You don't have files older than $DAYS days" 

This works by passing the output of find into a grep for the same thing, returns a failure exit code if it doesn’t find anything, or will success and echo the found lines if it does.

Everything after || will only execute if the preceding command fails.

Источник

Оцените статью
Adblock
detector