LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 06-13-2013, 11:10 AM   #1
sumeet inani
Member
 
Registered: Oct 2008
Posts: 895
Blog Entries: 26

Rep: Reputation: 48
writing bash script to check if file present on that partition


Aim is to use basic commands found in all distros.
Currently I am using tiny core which uses busybox.
I am trying to see in root directory of every partition if they have a file named 'i-have-oxford-kundli'
Code:
mounted=$(df | grep -i 'sd'| awk '{ print $(NF) }') 
echo mountpoints=$mounted
for word in $mounted; do 
echo looking in=$word
found=$(ls -l $word| grep -i i-have-oxford-kundli)
if [ $? -eq 0 ]; then 
echo $word has the desired file
echo over
else
echo not found
fi
done
I notice that 'over' is echoed for every mountpoint .
I want to run a set of commands when if condition is true not otherwise.
How can I do that ?
 
Old 06-13-2013, 11:14 AM   #2
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,260

Rep: Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947
Instead of running an ls, piping it to grep, and then checking the exit status, why not just check for the existence of the file directly?

Code:
if [ -f $word/i-have-oxford-kundli ]
 
Old 06-13-2013, 11:42 AM   #3
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387
@sumeet inani: You might want to add the -P flag to the df command. This will make sure that all entries stay on the same line and aren't wrapped over 2 lines.

Your script basically does what it is supposed to do, which is the most important thing. With that in mind: It can be done more efficient. Have a look at this:
Code:
while read MOUNTED
do
  echo "Looking in: $MOUNTED"
  if [[ -a "$MOUNTED/i-have-oxford-kundli" ]]
  then
    echo "Found it."
  else
    echo "Not found."
  fi
done < <(df -P | awk '/sd/ { print $(NF) }')
suicidaleggroll already mentioned -f (is it a regular file), -a (file exists) can also be used.

Last edited by druuna; 06-13-2013 at 11:47 AM.
 
Old 06-13-2013, 06:47 PM   #4
Firerat
Senior Member
 
Registered: Oct 2008
Distribution: Debian Jessie / sid
Posts: 1,471

Rep: Reputation: 444Reputation: 444Reputation: 444Reputation: 444Reputation: 444
Code:
busybox awk '{if (!system("test -a "$2"/i-have-oxford-kundli")){print "i-have-oxford-kundli exists in "$2}}' /proc/mounts
But, it fails for /
This is because I have been very lazy and 'hardcoded' / as a prefix to the filename


building on it

Code:
for hasOK in $(busybox awk '{if (!system("test -a "$2"/i-have-oxford-kundli")){print $2}}' /proc/mounts);do
    HasOK="$HasOK $hasOK"
done
Will fail if you have white space in mountpoints

Last edited by Firerat; 06-13-2013 at 06:49 PM.
 
Old 06-14-2013, 09:44 AM   #5
sumeet inani
Member
 
Registered: Oct 2008
Posts: 895
Blog Entries: 26

Original Poster
Rep: Reputation: 48
to suicidaleggroll , fireat , druuna

I will try your alternatives . My question was that : the second statement following 'then' got executed even when condition evaluated to false . How can that happen ?
 
Old 06-14-2013, 10:06 AM   #6
mddnix
Member
 
Registered: Mar 2013
Location: Bangalore, India
Distribution: Redhat, Arch, Ubuntu
Posts: 512

Rep: Reputation: 139Reputation: 139
Quote:
Originally Posted by sumeet inani View Post
My question was that : the second statement following 'then' got executed even when condition evaluated to false . How can that happen ?
PHP Code:
mounted=$(df grep -'sd'awk '{ print $(NF) }'
echo 
mountpoints=$mounted

for word in $mounted ; do 
    echo 
looking in=$word
    found
=$(ls -l $wordgrep -i i-have-oxford-kundli)

    if [ $? -
eq 0 ] ; then 
        
echo $word has the desired file
        
echo over
    
else
        echo 
not found
    fi

done 
Code:
$ ./kundli
mountpoints=/boot /dc /mnt/Win8 /mnt/Backup /media/Madhu_USB
looking in=/boot
not found
looking in=/dc
not found
looking in=/mnt/Win8
/mnt/Win8 has the desired file
over
looking in=/mnt/Backup
not found
looking in=/media/Madhu_USB
/media/Madhu_USB has the desired file
over
I see no wrong in the script. 'over' is only echoed on the partitions that has the 'i-have-oxford-kundli' file.

Edit: Just noticed that if you have LVM partitions, they dont show up by this script.

Last edited by mddnix; 06-14-2013 at 10:10 AM.
 
Old 06-14-2013, 10:16 AM   #7
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387
Quote:
Originally Posted by sumeet inani View Post
My question was that : the second statement following 'then' got executed even when condition evaluated to false . How can that happen ?
You're code works when it comes to the echo over part. Don't know why it happens to you.

Quote:
Originally Posted by mddesai
Edit: Just noticed that if you have LVM partitions, they dont show up by this script.
That's why I suggested using the -P option (df -P instead of plain df). df uses a width of 80 by default which will wrap lines.
 
Old 06-14-2013, 10:25 AM   #8
mddnix
Member
 
Registered: Mar 2013
Location: Bangalore, India
Distribution: Redhat, Arch, Ubuntu
Posts: 512

Rep: Reputation: 139Reputation: 139
Quote:
Originally Posted by druuna View Post
That's why I suggested using the -P option (df -P instead of plain df). df uses a width of 80 by default which will wrap lines.
-P option will put all lines in their seperate line, but since OP has filtered only 'sd' in grep, LVM partitions wont show up. instead OP can use

Code:
mounted=$(df -P | grep -i 'sd\|mapper' | awk '{ print $(NF) }')
 
Old 06-14-2013, 10:32 AM   #9
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387Reputation: 2387
Quote:
Originally Posted by mddesai View Post
but since OP has filtered only 'sd' in grep, LVM partitions wont show up. instead OP can use

Code:
mounted=$(df -P | grep -i 'sd\|mapper' | awk '{ print $(NF) }')
Very valid point!

This would be more elegant and resource friendly:
Code:
df -P | awk '/(mapper|sd)/ { print $(NF)}'
 
Old 06-14-2013, 11:11 AM   #10
mddnix
Member
 
Registered: Mar 2013
Location: Bangalore, India
Distribution: Redhat, Arch, Ubuntu
Posts: 512

Rep: Reputation: 139Reputation: 139
Quote:
Originally Posted by druuna View Post
Code:
df -P | awk '/(mapper|sd)/ { print $(NF)}'
enhancing your code a little, it can be further made to pattern-match only from first field, so that search wont pickup 'sd' or 'mapper' from any other field, just in case...
Code:
df -P | awk '$1~/(mapper|sd)/ { print $(NF)}'
...just a thought.
 
Old 06-14-2013, 03:42 PM   #11
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
grep is lighter than awk, so it might be better to do the line filtering with that, and do the field splitting with read instead.

Code:
while read -r _ _ _ _ _ MOUNTED ; do
    ...
done < <( df -P | grep -E '^(mapper|sd)'
In fact, since df doesn't generally produce that much input, I think it might actually be even faster to do all the filtering in the loop.

Code:
match='^(mapper|sd)'

while read -r fs _ _ _ _ MOUNTED ; do
    [[ $fs =~ $match ]] || continue 
    ...
done < <( df -P )
Edit: I just noticed this is being done in busybox. I imagine the advanced bash features I used above may not be available.

Last edited by David the H.; 06-14-2013 at 03:45 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash Shell Script - Check SQL file for corruption RML1992 Linux - General 3 09-14-2012 01:47 AM
Need advice on writing a script to check if a file exists and send notification santosh662 Linux - Server 20 04-09-2012 09:57 AM
bash script file access check? viperuk Linux - Newbie 1 12-10-2010 09:20 PM
BASH script Ė reading and writing variables to a separate file morrolan Programming 10 09-20-2005 08:45 AM
Writing to a file - Bash script Skute Programming 2 03-15-2004 05:41 AM


All times are GMT -5. The time now is 04:00 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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration