Solved

bash if file exists, go to function

Posted on 2014-07-30
21
277 Views
Last Modified: 2014-08-01
Using bash scripting,...

I need the following which I will put in a loop to keep checking;

if file exists, then go to function
0
Comment
Question by:projects
  • 10
  • 9
  • 2
21 Comments
 
LVL 3

Expert Comment

by:Mark Olsen
Comment Utility
Try the "-e" (file exists) conditional:

if [ -e "filename" ]
then
   doFunction
fi

Open in new window

0
 
LVL 3

Expert Comment

by:Mark Olsen
Comment Utility
To expand on my first comment, here is a good list of file conditionals:

http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html
0
 

Author Comment

by:projects
Comment Utility
Does the trick just fine. Can you add just one small thing.
I'd like to monitor for a text file like '*.txt' for example.

I won't know what the full file name is so I need to first check it's full file name by looking for '*.txt' then using that as input for my function.

It will be the only .txt file there.

My attempt is not working.

function file_check()
{
        openfile=$( ls -la /temp/*.txt | awk '{print $9}' )
        if [ -e "/temp/... what goes here??? *" ]
        then
echo "$OPENFILE"

# If there is a *.txt file in /temp, then I want to know it's full name. Then, do something
# with the file, say delete it for testing.
# so rm -f /temp/whateverthefilenameis.txt

        fi
}
0
 
LVL 3

Expert Comment

by:Mark Olsen
Comment Utility
Disclaimer: my bash is a bit rusty, I'm translating how I would do this in Perl into bash.

If you are already iterating through a list of files you can add a regular expression (regex) to the test. This looks for strings that end in ".txt".

if [ $filename =~ ".txt$" -a -e $filename ]
then
   doFunction
fi

Open in new window


note: The "-a" operator is the "and" operator.
0
 

Author Comment

by:projects
Comment Utility
Sorry, not following that anymore.
I need to know what the file name is.
Once I know what the file name is, I need to use it as input to something.
As a test, I'd like to say delete it or rename it to something else.
0
 

Author Comment

by:projects
Comment Utility
I am able to get the file name and do something with it now but I still need to loop check to see if there is a file in the directory ending with *.txt
So far, what I have isn't quite working.

function file_check()
{
        if [ $filename =~ "/temp/.txt$" -a -e $filename ]
        then
        OPENFILE="$( ls -la /temp/*.txt | awk '{print $9}' )"
        cp $OPENFILE $OPENFILE.two
        fi
}

Guessing I have a mismatch between $FILENAME and $OPENFILE
0
 
LVL 3

Expert Comment

by:Mark Olsen
Comment Utility
Ok, let's give this a try. It will find any .txt files in the directory and give you the hook to issue a command:

for txtfile in $(ls -la /temp/*.txt | awk '{print $9}'); do
   cp $txtfile $txtfile.two
done

Open in new window

0
 

Author Comment

by:projects
Comment Utility
So if there is no text file, then the script will continue on right.

This works as a stand alone script but when I add it as a function, it returns an error;

ls: /temp/*.txt: No such file or directory
0
 
LVL 3

Expert Comment

by:Mark Olsen
Comment Utility
Seems like if there is no .txt file that ls command is failing. Let's try this approach which iterates through all of the files in the /temp directory and looks for the match with a regex.

for filename in $(ls /temp); do
   if [[ $filename =~ .txt$ ]]
   then
       cp $filename $filename.two
   fi
done

Open in new window

0
 

Author Comment

by:projects
Comment Utility
I am using this as a function in an existing script;

function file_check()
{
        for filename in $(ls /temp); do
        if [[ $filename =~ .txt$ ]]
        then
        rm $filename
        fi
}

When I run my script, it is terminating complaining about the last 'done' statement.
I've tried commenting out the done and fi in this outage so obviously have a syntax issue going on now.

I'm also getting the following error;

 ./script.sh
./script.sh: line 110: syntax error near unexpected token `}'
./script.sh: line 110: `}'

Line 110 is the last } above.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 3

Accepted Solution

by:
Mark Olsen earned 155 total points
Comment Utility
I just wrapped my example code and was able to get it to run:

function file_check()
{
   for filename in $(ls); do
      if [[ $filename =~ .txt$ ]]
      then
         rm $filename
      fi
   done
}

Open in new window

0
 

Author Comment

by:projects
Comment Utility
Either way, I'll award you this because it's just a syntax issue I need to resolve.

Thanks very much!
0
 
LVL 3

Expert Comment

by:Mark Olsen
Comment Utility
Thanks, it was a bit of a learning experience myself with the bash syntax. Now back to my cozy Java and Perl...
0
 

Author Comment

by:projects
Comment Utility
Oops. Just one small problem.
I got it to work but I need it to skip the command IF no file exists.
So if no file, then don't run the command, just skip it.
0
 
LVL 3

Expert Comment

by:Mark Olsen
Comment Utility
If no files exist then there is nothing to iterate on in the "ls" command's loop, thus it won't test for the filename match. To add an extra layer of checking you could do this:

function file_check()
{
   for filename in $(ls); do
      if [ -e $filename ]
      then
         if [[ $filename =~ .txt$ ]]
         then
            echo $filename
         fi
      fi
   done
}

Open in new window


Replace the "echo" with the command you wish to do, this was just in place so I could make sure it was getting to the command point.
0
 

Author Comment

by:projects
Comment Utility
Perfect! Thanks very much for the extra little bit :)
0
 
LVL 3

Expert Comment

by:Mark Olsen
Comment Utility
You're welcome, glad it all came together.
0
 
LVL 48

Expert Comment

by:Tintin
Comment Utility
Note that

function file_check()
{
   for filename in $(ls); do
      if [[ $filename =~ .txt$ ]]
      then
         rm $filename
      fi
   done
}

Open in new window


is equivalent to

function file_check()
{
  rm -f *.txt
}

Open in new window

0
 

Author Comment

by:projects
Comment Utility
Oh, yes, I see what you are saying but I just used rm -f as a silly example.

It actually looks like this now, which is still not perfect but better;

function update_check()
{
        # Check for new update file. If there is one, download it.
        curl -s -k --key sum.key --cert sum.crt https://server/update.php -u "$USERNAME:$PASSWD" -o $FWFILE

        for filename in $(ls /tmp); do
        if [ -e $filename ]
            then
                if [[ $filename =~ .bin$ ]]
                then
#                cat $filename >/tmp/updates.txt
echo "There is an upgrade"
                fi
            fi
        done
}

Open in new window


You always seem to help me after the points are given out. Maybe you can just get your own with another of my questions :).

http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28487404.html
0
 
LVL 48

Expert Comment

by:Tintin
Comment Utility
I'd write the above function as:

function update_check()
{
        # Check for new update file. If there is one, download it.
        curl -s -k --key sum.key --cert sum.crt https://server/update.php -u "$USERNAME:$PASSWD" -o $FWFILE

       if file=$(ls /tmp/*.bin 2>/dev/null) 
       then
              echo "There is an upgrade"
              echo "$file" >/tmp/updates
       fi
      
}

Open in new window

0
 

Author Comment

by:projects
Comment Utility
Based on the following question;
http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28487404.html

My function now looks like;

function file_check()
{
        # Check for new  file
        echo "Checking for file update"
        curl -s -k --key sum.key --cert sum.crt https://server/fileupdate.php?id=open-$USERNAME.bin -u "$USERNAME:$PASSWD" -o $UPDATE

        for filename in $(ls /tmp); do
        if [ -e $filename ]
            then
                if [[ $filename =~ .bin$ ]]
                then
# do something with the file
mv $UPDATE $UPDATE.two
                fi
            fi
        done
}

Open in new window


In the end, I have no idea how safe the function is nor the php side is. Someone mentioned script kiddies in my other post for the php side of this.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

The following is a collection of cases for strange behaviour when using advanced techniques in DOS batch files. You should have some basic experience in batch "programming", as I'm assuming some knowledge and not further explain the basics. For some…
Utilizing an array to gracefully append to a list of EmailAddresses
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now