LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 05-05-2013, 12:02 PM   #1
balakrishnay
Member
 
Registered: Sep 2009
Posts: 31

Rep: Reputation: 15
Find command issues over while loop or for loops


Hi All,

The below find command returns nothing sometimes , if so it wont even enter into the loop to continue with rest of the code how to handle this ?

Appreciated your help ASAP.


for file in `find /oracle/admin/XXXXX/udump/bkp/ -type f -size +20M -exec ls -1 {} \;`

do
if [ ! -f "$file" ]
then
echo "File \"$file\" does not exist."
exit 1
fi
proc=`echo $file | awk -F"_" '{print $3}'`
active_pid=`ps aux | grep "$proc" | grep -v grep|wc -l`

if [ "$active_id" -eq 1 ]
then
exec "/usr/tools/oracle/Standard/script/DB_Trace_Off.ksh" $INST_NAME $active_pid
else
gzip $file
fi

done

Regards
Bala
 
Old 05-05-2013, 02:51 PM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Code:
#!/bin/bash -vx
for file in `find /oracle/admin/XXXXX/udump/bkp/ -type f -size +20M -exec ls -1 {} \;`

   do
   if [ ! -f "$file" ]
   then
       echo "File \"$file\" does not exist."
        exit 1
   fi
      proc=`echo $file | awk -F"_" '{print $3}'`
      active_pid=`ps aux | grep "$proc" | grep -v grep|wc -l`

   if [ "$active_id" -eq 1 ]
   then
        exec "/usr/tools/oracle/Standard/script/DB_Trace_Off.ksh" $INST_NAME $active_pid
   else
        gzip $file
   fi

done
exit 0
Run that as '/path/to/script 2>&1 | tee /tmp/output.txt' and then read back the "output.txt" file, see what 'find' finds and how it's used in the script.

*And since you mentioned the ASAP FLA you will also want to read these:
http://mywiki.wooledge.org/ParsingLs
http://mywiki.wooledge.orgDontReadLinesWithFor
http://mywiki.wooledge.org/UsingFind
http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting
http://mywiki.wooledge.org/Quotes
as there's nothing quicker than you reading stuff yourself.
 
Old 05-05-2013, 08:48 PM   #3
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,573

Rep: Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142
Quote:
Originally Posted by balakrishnay View Post
Hi All,

The below find command returns nothing sometimes , if so it wont even enter into the loop to continue with rest of the code how to handle this ?
Of course it doesn't enter the for loop. The for loop is looping over each match from find, if find doesn't find anything, there's nothing for the for loop to do. What, exactly, would you like for the code to do in this case, since it sounds like it's doing exactly what it's supposed to be doing.
 
Old 05-06-2013, 03:13 AM   #4
Beryllos
Member
 
Registered: Apr 2013
Location: Massachusetts
Distribution: Debian
Posts: 529

Rep: Reputation: 319Reputation: 319Reputation: 319Reputation: 319
If there is something you need to do when the find command doesn't find anything, you could test for that and take the appropriate action, for example:
Code:
#!/bin/bash
FILE_LIST=$(find . -type f -print) # by the way, I use -print instead of -exec ls -1 {} \;
if [ -z "$FILE_LIST" ] # test for zero-length string (no files found)
then
    echo "The file list is empty."
else
    for FILE in $FILE_LIST
    do
        echo "list item:" $FILE
    done
fi
When there are no files to be found, I get:
Code:
tony> ../looptest
The file list is empty.
When there are files called Alice, Bob, and Charlie, I get:
Code:
tony> ../looptest
list item: ./Charlie
list item: ./Alice
list item: ./Bob
Slightly off-topic: Neither my script nor the script in the OP works correctly if the filename has whitespace (like "Bob Marley"). Then the output for 3 files appears to have more than 3 items:
Code:
tony> ../looptest
list item: ./Bob
list item: Marley
list item: ./Charlie
list item: ./Alice
This is because of the way the "for loop" processes lists which are delimited by whitespace. I have read the man pages of find, for, and ls, and I have tried a few tricks, but so far I have not found a solution to this particular problem. Similar problems may exist also when other special characters are present in the filename.
 
Old 05-06-2013, 09:07 AM   #5
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,573

Rep: Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142
Quote:
Originally Posted by Beryllos View Post
[/CODE]Slightly off-topic: Neither my script nor the script in the OP works correctly if the filename has whitespace (like "Bob Marley"). Then the output for 3 files appears to have more than 3 items:
Code:
tony> ../looptest
list item: ./Bob
list item: Marley
list item: ./Charlie
list item: ./Alice
This is because of the way the "for loop" processes lists which are delimited by whitespace. I have read the man pages of find, for, and ls, and I have tried a few tricks, but so far I have not found a solution to this particular problem. Similar problems may exist also when other special characters are present in the filename.
The easiest solution is to use "while read" instead of "for":
Code:
find . | while read -r file
 
1 members found this post helpful.
Old 05-06-2013, 03:33 PM   #6
Beryllos
Member
 
Registered: Apr 2013
Location: Massachusetts
Distribution: Debian
Posts: 529

Rep: Reputation: 319Reputation: 319Reputation: 319Reputation: 319
One More Thing...

Quote:
Originally Posted by suicidaleggroll View Post
The easiest solution is to use "while read" instead of "for":
Code:
find . | while read -r file
Thanks. That works great for filenames with whitespace. Just to make it more interesting, I created files called "*" and "--help"
Code:
tony> ls
*  Alice  Bob Marley  Charlie  --help
which lead to all sorts of confusion with everyday bash commands. However, if I use double quotes as shown in the first line below, it seems to work:
Code:
tony> find . -type f | while read -r file; do echo "$file"; cat "$file"; rm -v "$file"; done
./Bob Marley
This is the contents of file named "Bob Marley"
removed ‘./Bob Marley’
./*
This is the contents of file named "*"
removed ‘./*’
./--help
This is the contents of file named "--help"
removed ‘./--help’
./Charlie
This is the contents of file named "Charlie"
removed ‘./Charlie’
./Alice
This is the contents of file named "Alice"
removed ‘./Alice’
tony> ls
 
Old 05-06-2013, 06:11 PM   #7
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,665
Blog Entries: 4

Rep: Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945
As a general rule-of-thumb, in any language or environment, "finders" need to be allowed to "do their own thing, whatever it is, without interruption." If you need to process the list-of-whatevers that they create, then you should plan to "let them generate it, completely, however they want to do it," first, then "iterate through the list that they produced."
 
Old 05-06-2013, 06:11 PM   #8
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,780

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
Try it on a filename that contains a newline character.
 
1 members found this post helpful.
Old 05-06-2013, 08:19 PM   #9
Beryllos
Member
 
Registered: Apr 2013
Location: Massachusetts
Distribution: Debian
Posts: 529

Rep: Reputation: 319Reputation: 319Reputation: 319Reputation: 319
Quote:
Originally Posted by rknichols View Post
Try it on a filename that contains a newline character.
Okay, I tried it. The method I outlined above does not work.
Code:
tony> FILE=`echo -e new'\n'line`
tony> echo Hello World\! > "$FILE"
tony> ls
new?line
tony> ls --show-control-chars
new
line
tony> find . -type f | while read -r file; do rm -v "$file"; done
rm: cannot remove ‘./new’: No such file or directory
rm: cannot remove ‘line’: No such file or directory
tony> rm -v new?line
removed ‘new\nline’
I guess that makes sense because the read command expects items to be separated by newline characters.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Sleep inside for loop inside while loop causing issues. TheOnlyQ Programming 13 12-19-2012 12:59 PM
Scripting--need to create a 2 loops in a loop--can someone help timonthy28 Linux - Newbie 10 11-13-2012 01:59 AM
piping output of find to another command or loop steven19782007 Linux - Newbie 6 06-25-2009 05:29 PM
C++ FOR loop issues -- C++ Newbie Please Help BenRichards Programming 2 02-22-2005 03:17 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 04:51 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration