I want to return an exit status of 0 if the output is empty and 1 otherwise:
find /this/is/a/path/ -name core.*
When you say you want it to return a particular number, are you referring to the exit status? If so:
[[ -z `find /this/is/a/path/ -name core.*` ]]
And since you only care about a yes/no response, you may want to change your find to this:
[[ -z `find /this/is/a/path/ -name core.* -print -quit` ]]
which will stop after the first core file found. Without that, if the root directory is large, the find could take a while.
Here's my version. :)
[ -z "$(find /this/is/a/path/ -name 'core.*')" ] && true
Edited for brevity:
[ -z "$(find /this/is/a/path/ -name 'core.*')" ]
There are probably many variants, but this is one:
test $(find /this/is/a/path/ -name core.* | wc -c) -eq 0
Perhaps this
find /this/is/a/path/ -name 'core.*' | read
I am using this:
if test $(find $path -name value | wc -c) -eq 0
then
echo "has no value"
exit
else
echo "perfect !!!"
fi
Related
how can I check if multiple files of a certain type exists in shell script?
I've tried this:
[ -e $HOME/somefolder/Images/*.jpeg ] && echo "ok"
[ -f $HOME/somefolder/Images/*.jpeg ] && echo "ok"
but in both cases I got:
[: too many arguments
I would use the below. find is an excellent utility.
test -n "$(find $HOME/somefolder/Images/ -maxdepth 1 -name '*.jpeg' -print -quit)" && echo "ok" || echo "not ok"
As an alternative, consider the pure-bash solution.
if [ "$(shopt -s nullglob ; echo /path/to/file*.jpeg)" ] ; then
...
fi
I have this code:
if [[ $(find /path/to/folder1 -type f -not -path "*configs*" -size -800k 2>/dev/null) ]]; then
echo "[[Warning]]: The files size is under 800 Kilobytes"
if [[ $(find /path/to/another/folder -type f \( ! -iname "123.file*" \) -not -path "*logs*" -size -40k 2>/dev/null) ]]; then
echo "[[Warning]]: The file size is under 40 Kilobytes"
fi
else
Run a command here
fi
The target is:
Get an echo if a file under size found in any of the above paths or get both echo if a file under size found on both paths and run the command at the end only if not files under size found at any of the above two paths.
Both checks are tested and working but it seems that I have the if or else statements in wrong order?
That should work what you have. An easier way would be to use OR (||) in structure below. If both of those statements are false, then you run command.
if statementA || statementB then...
else ...
Your else is already executed when the first if gets false. You could do a
if [[ $(find ....) ]] || [[ $(find ....) ]]; then
else
run
fi
or
if [[ -n $(find ....) || -n $(find ....) ]]; then
else
run
fi
but this would only take care about the running command; you want, however, also display an individual message if the find commands succeed.
There are several possibilities. The easiest would be IMO to use a control variable:
run_command=1
if [[ $(find ....) ]]; then
echo ....
run_command=0
fi
if [[ $(find ....) ]]; then
echo ....
run_command=0
fi
if ((run_command == 1)); then
run ...
fi
if [[ -n $(find $path -name "$string*") ]]
then
<stuff>
else
<stuff>
fi
I want to reverse the above search like
if [[ ! -n $(find $path -name "$string*") ]]
then
<stuff>
else
<stuff>
fi
But it wont allow this because here I am checking the find commands output
any clue.thanks for help
You can reverse the search in find itself using:
find "$path" ! -name "$string*"
btw this is also valid:
[[ ! -n $(find $path -name "$string*") ]]
Or else you can use -z:
[[ -z $(find $path -name "$string*") ]]
if [ ! -f ./* ]; then
for files in $(find . -maxdepth 1 -type f); do
echo $files
else
echo Nothing here
fi
Returns
syntax error near unexpected token `else'
New to this. Can anyone point me to what I did wrong?
You forgot done!
if [ ! -f ./* ]; then
for files in $(find . -maxdepth 1 -type f); do
echo $files
done
else
echo Nothing here
fi
The reason you get a syntax error is because you are not ending the loop with the "done" statement. You should be using a while loop, instead of a for loop in this case, as the for loop will break if any of the filenames contain spaces or newlines.
Also, the test command you have issued will also give a syntax error if the glob expands to multiple files.
$ [ ! -f ./* ]
bash: [: too many arguments
Here is a better way to check if the directory contains any files:
files=(./*) # populate an array with file or directory names
hasfile=false
for file in "${files[#]}"; do
if [[ -f $file ]]; then
hasfile=true
break
fi
done
if $hasfile; then
while read -r file; do
echo "$file"
done < <(find . -maxdepth 1 -type f)
fi
Also, you could simply replace the while loop with find -print if you have GNU find:
if $hasfile; then
find . -maxdepth 1 -type f -print
fi
The syntax for "for" is
for: for NAME [in WORDS ... ;] do COMMANDS; done
You are missing the "done"
Try
if [ ! -f ./* ]; then
for files in $(find . -maxdepth 1 -type f); do
echo $files
done
else
echo Nothing here
fi
BTW, did you mean echo with lowercase rather than ECHO?
I wonder if someone could explain why a while loop treats multipe test conditions differently to an if loop. I have 2 tests that i verified came out as True and False:
Bash$ test ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)"; echo $?
0
Bash$ test ! -e "unsentData.tmp"; echo $?
1
Bash$
When I ANDed these 2 tests into an if statement I got an aggregate of False as expected:
Bash$ if [ ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] && [ ! -e "unsentData.tmp" ]; then echo "True"; else echo "False"; fi
False
Bash$
Now when I put the 2 tests into a while loop I expected a sleep until both conditions were met but instead I got immediately a true result.
Bash$ while [ ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] && [ ! -e "unsentData.tmp" ]; do sleep 1; done; echo -e "All files Exist\n$(ls /opt/pcf/mfe/unsentXmlToTSM/xmlConnection0_TSM/)"
All files Exist
unsentData.tmp
Bash$
What am I missing here? I simply want to write something that waits until the 2 conditions are met before it breaks out of the loop
A
Your assumption is worng i think. While does execute the code between do and done while (as long as) the condition holds true. Your conditions combined evaluate to false, as seen in the output of your if-statement. Thus the body of the while loop never gets executed.
Try:
while ! ( [ ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] &&
[ ! -e "unsentData.tmp" ] )
do
sleep 1
done
echo -e "All files Exist\n$(ls /opt/pcf/mfe/unsentXmlToTSM/xmlConnection0_TSM/)"
A while loop executes as long as ("while") its condition is true; it sounds like you want to run the loop until its condition is true. bash has an until loop which does exactly this:
until [ ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] && [ ! -e "unsentData.tmp" ]; do
sleep 1
done
echo -e "All files Exist\n$(ls /opt/pcf/mfe/unsentXmlToTSM/xmlConnection0_TSM/)"
Or you can just negate the condition (i.e. use "while there are files left, do..." rather than "until all files are done, do..."). In this case that just means removing the negations of the individual conditions and switching the and to an or:
while [ -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] || [ -e "unsentData.tmp" ]; do
sleep 1
done
echo -e "All files Exist\n$(ls /opt/pcf/mfe/unsentXmlToTSM/xmlConnection0_TSM/)"
while [ ! -n "$(find . -maxdepth 1 -name '*.xml' -print -quit)" ] && [ ! -e "unsentData.tmp" ]
do sleep 1
done
==>
while false
do sleep 1
done
so the do sleep 1 didn't run at all.