LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
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 03-11-2010, 02:42 AM   #1
Skillz
Member
 
Registered: Sep 2007
Posts: 252

Rep: Reputation: 32
Optimize this script...


Hey guys,

I need a little assistance. I need this script to delete all files that are not that of *.uz including files starting with a . such as, but not limited to, .htaccess.

Code:
#!/bin/bash

 SRC=/home/ftp/uploads/uz/
 DEST=/home/uz/www/
 set -e
 cd $SRC || exit 1

 ls -l -- *.uz | awk '{print $3, $4, $NF}' | while read user group file
 do
   if [ ! -f $DEST/${file} ] ; then
     {
        mv -- ${file} $DEST/${file}
        chown ${user}:${group} $DEST/${file}
      }
   else
       rm -f -- $SRC/${file}
   fi
 done

 for i in $(ls | grep -v ".uz")
   do
      rm -f -- "$i"
   done
I believe it does delete all files, but for some reason I think it's skipping the files beginning with a . I have some bot I believe that's gun hoe on logging into my anonymous FTP server and uploading a .htaccess file in all the directories. It's not that big of a deal, as it's only an FTP server...so the file doesn't get moved to a HTTP environment, but it's annoying that I have to go in and manually delete them. I want the script to do it for me.

If I was to edit the script to do that, this is what I would do. Is this correct?

Code:
#!/bin/bash

 SRC=/home/ftp/uploads/uz/
 DEST=/home/uz/www/
 set -e
 cd $SRC || exit 1

 ls -l -- *.uz | awk '{print $3, $4, $NF}' | while read user group file
 do
   if [ ! -f $DEST/${file} ] ; then
     {
        mv -- ${file} $DEST/${file}
        chown ${user}:${group} $DEST/${file}
      }
   else
       rm -f -- $SRC/${file}
   fi
 done

 for i in $(ls | grep -v ".uz")
   do
      rm -f -- "$i"
   done
 
rm -Rf -- *
I just think, that if by accident this script was ran outside of the source directory, like..the root directory for example, it could really destroy my server.

Last edited by Skillz; 03-11-2010 at 02:45 AM.
 
Old 03-11-2010, 08:33 PM   #2
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
ls -Al might do what you want.
 
Old 05-18-2010, 10:29 PM   #3
Skillz
Member
 
Registered: Sep 2007
Posts: 252

Original Poster
Rep: Reputation: 32
Another problem I've facing with this script. If any of the file names contain a space, it stops the script. It will only read the information after the space, so when it goes to move it, it returns a "not found" error and stops the script.

What can I do, so that it will keep the file names, with spaces, together?
 
Old 05-18-2010, 11:05 PM   #4
Skillz
Member
 
Registered: Sep 2007
Posts: 252

Original Poster
Rep: Reputation: 32
This is what I have come up with, but I am getting an error:

Code:
#!/bin/bash

 SRC=/home/uploadu/uploads/redirect/
 DEST=/home/uzutfi/public_html/
 set -e
 cd $SRC || exit 1

 find -iname "*.uz" | awk '{print $3, $4, $NF}' | while read file
 do
   if [ ! -f $DEST/"${file}" ] ; then
     {
        mv -- "${file}" $DEST/"${file"}
        chown ${user}:${group} $DEST/"${file}"
      }
   else
       rm -f -- $SRC/"${file}"
   fi
 done

for i in $(ls | grep -v ".uz")
   do
      rm -f -- "$i"
   done
What am I doing wrong? I get this error:
./move_test.sh: line 22: unexpected EOF while looking for matching `"'
 
Old 05-18-2010, 11:15 PM   #5
alunduil
Member
 
Registered: Feb 2005
Location: San Antonio, TX
Distribution: Gentoo
Posts: 684

Rep: Reputation: 62
Why not use a find command:

Code:
find <directory> -type f -name '<pattern>' -or -name '.<pattern>' -exec rm '{}' \;
Regards,

Alunduil
 
Old 05-18-2010, 11:34 PM   #6
Skillz
Member
 
Registered: Sep 2007
Posts: 252

Original Poster
Rep: Reputation: 32
Well I am using the find command towards the top of the script, but the last portion of the script ran just fine but since I made the change to use the find command, instead of the previous ls command, now it's telling me the last part of the script is ending too soon? Why?

There is something wrong with this section:

Code:
for i in $(ls | grep -v ".uz")
   do
      rm -f -- "$i"
   done
I tried to change it to this, but I got the same error:

Code:
for i in $(find | grep -v ".uz")
   do
      rm -f -- "$i"
   done
I'm not sure what I am doing wrong.
 
Old 05-18-2010, 11:48 PM   #7
alunduil
Member
 
Registered: Feb 2005
Location: San Antonio, TX
Distribution: Gentoo
Posts: 684

Rep: Reputation: 62
I don't see why you need to use find in that way personally. I recommend (with least change to how your code behaves) going back to you original ls version and making it look like this:

Code:
for i in $(ls -1 | grep -v ".uz"); do
Regards,

Alunduil
 
Old 05-18-2010, 11:50 PM   #8
Skillz
Member
 
Registered: Sep 2007
Posts: 252

Original Poster
Rep: Reputation: 32
Quote:
Originally Posted by alunduil View Post
I don't see why you need to use find in that way personally. I recommend (with least change to how your code behaves) going back to you original ls version and making it look like this:

Code:
for i in $(ls -1 | grep -v ".uz"); do
Regards,

Alunduil
well I have the do on a next line, so I added the ; at the end of that line then tested the script again. Still getting the same error.

./move_test.sh: line 22: unexpected EOF while looking for matching `"'

I then removed the do, that was on the next line and changed the line to look like the one you suggested. Still the same error.
 
Old 05-19-2010, 12:01 AM   #9
piratesmack
Member
 
Registered: Feb 2009
Distribution: Slackware, Arch
Posts: 519

Rep: Reputation: 142Reputation: 142
Code:
mv -- "${file}" $DEST/"${file"}
Change it to
Code:
mv -- "${file}" $DEST/"${file}"
 
Old 05-19-2010, 12:02 AM   #10
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
What am I doing wrong? I get this error:
./move_test.sh: line 22: unexpected EOF while looking for matching `"'
The trasposed } and " in mv -- "${file}" $DEST/"${file"} are wrong. BTW, none of the { and } are actually required; they are not wrong but not necessary either.
 
Old 05-19-2010, 12:10 AM   #11
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by Skillz View Post
What can I do, so that it will keep the file names, with spaces, together?
This will cope with spaces and any other possible character in file names
Code:
while IFS= read -r -d '' file
do
   commands using "$file"
done < <(find . -type f -iname '*.uz' -print0)
EDIT: when testing a script that may cause data loss it is prudent to echo the mv, rm whatever commands at first so you can see that the script is generating the correct commands. When ready to run for real, remove the echo in front of the mv, rm whatever.

Last edited by catkin; 05-19-2010 at 12:13 AM.
 
Old 05-19-2010, 01:40 AM   #12
Skillz
Member
 
Registered: Sep 2007
Posts: 252

Original Poster
Rep: Reputation: 32
Oh wow I didn't even think to check the rest of the script for errors, I was just focusing on and around line 22.

Where do I put that code, catkin?
 
Old 05-19-2010, 01:56 AM   #13
Skillz
Member
 
Registered: Sep 2007
Posts: 252

Original Poster
Rep: Reputation: 32
Hmm I think I got it all working now.

This is the script.

Code:
#!/bin/bash

 SRC=/home/uploadu/uploads/redirect/
 DEST=/home/uzutfi/public_html/
 set -e
 cd $SRC || exit 1

find -iname "*.uz" | while read file
 do
   if [ ! -f $DEST/"${file}" ] ; then
     {
        mv -- "${file}" "$DEST/${file}"
        chown ${user}:${group} "$DEST/${file}"
      }
   else
       rm -f -- "$SRC/${file}"
   fi
 done

for i in $(ls -l | grep -v "*.uz");
   do
      rm -f -- "$i"
   done
PS
All the data this was moving around and deleting I have a backup of it. So nothing could have been lost, just real life problems the script has ran into with users uploading custom files with weird, unstandardized names.

So far it has solved a bunch of issues.

File names that begin with -, I have fixed with the -- option and file names with spaces I have solved with the find command, I also had a problem with any files that contained a uz in them, they would have ignored with the last rm command. So files that were that of .uz2 extensions were ignored, got that solved as well.

Any other suggestions, specifically security issues that may be encountered?

Would removing the { and } brackets make the script run faster? Currently the script is executed every 5 minutes.

Last edited by Skillz; 05-19-2010 at 01:59 AM.
 
Old 05-19-2010, 03:11 AM   #14
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
If you want more speed, I'd use Perl with the File::Basename module which can extract the filename components eg

# Get filename components
($filename, $filedir, $filext) = fileparse($orig_filename, '\..*');

and

opendir, readdir, closedir fns
http://perldoc.perl.org/functions/readdir.html
 
Old 05-19-2010, 03:21 AM   #15
Skillz
Member
 
Registered: Sep 2007
Posts: 252

Original Poster
Rep: Reputation: 32
Quote:
Originally Posted by chrism01 View Post
If you want more speed, I'd use Perl with the File::Basename module which can extract the filename components eg

# Get filename components
($filename, $filedir, $filext) = fileparse($orig_filename, '\..*');

and

opendir, readdir, closedir fns
http://perldoc.perl.org/functions/readdir.html
Well, I'm not worried about it being as fast as possible. Just wondering if using the { } in those areas will make this particular script slower. If so, I can easily remove them. If they wont make any difference, then the script I'm currently using is plenty fast enough. Usually only ~10 files every 5 minutes can be uploaded every 5 minutes by a client, depending on the connection speed. The only time it has to move a bunch of files is when the script breaks, though I think I have solved all those issues now. I had to work with ~2000 files just now and it only took a couple minutes to complete them all. Even though I ran the script about 4 or 5 times, with the same files to ensure it was working correctly.
 
  


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
HOW can i optimize my lighttpd? need help! gavin2u Linux - Server 4 08-13-2008 07:00 PM
can I optimize this kushalkoolwal Programming 5 10-21-2005 09:05 PM
Php image optimize script htmlcoder Programming 0 03-19-2005 03:23 AM
Optimize/Prefix rogk Linux - Software 1 07-25-2004 05:04 AM
how could I optimize bittorrent? rcerrillo General 0 07-04-2004 06:52 AM

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

All times are GMT -5. The time now is 01:24 AM.

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