ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
I am trying to get a script to move files from one dir to another when they are older than 180 days. What I have so far:
Quote:
#Modify this to change the destination of the various components
BASE_DIR="/sumfiles
TARGET_DIR="/backup-sumfiles
AGE=180
echo "Moving all files older than $AGE days from $BASE_DIR -> $TARGET_DIR"
echo
# Make sure that our target directory exists
mkdir -p $TARGET_DIR
# Move the files
for i in `find $BASE_DIR -type f -mtime +$AGE`; do
cp "$i" $TARGET_DIR/ --parents -p
if (( $? != 0 )); then
echo "FAILED TO COPY $i; BAILING OUT"
exit 1;
fi
rm "$i"
echo "Removed: \"$i\""
done
This works great, right up until I hit a filename that contains spaces. Just quoting my $i doesn't seem to work (now, why don't all mtools have a -0 option? for the love of god!) I would *LOVE* to be able to just move the files, but I need to maintain the directory structure under which the files reside (hence --parents).
Anyone have any suggestions on how I can make it that last foot-and-a-half?
But I couldn't figure out how to get xargs to like the &&.
Any suggestions? I'd prefer to use the for loop from the first method as it is cleaner, easier to read and way easier to comment for the next guy that comes along.
note: maintaining the file attribs and directory structure are the key requirements here.
This is how I did something similar for Oracle binary files as they contain spaces in their names:
Code:
#!/bin/ksh
# Simple script to change owner of files from original owner to new owner.
# jlightner 23-Aug-2005
#
# Usage: chownit olduid newuid
#
find / -user $1 -fsonly vxfs |awk '{print "\""$0"\""}'|xargs chown -h $2
What I found was I had to escape the quotes with the \ but then quote the escape characters themselves. $0 in awk means "the entire line" so what the abvoe does is send the entire line (file name) with a quote at the beginning and a quote at the end to xargs. All the other quotes in that print statement are just so it will use the escape as an escape rather than a litteral.
(REGEXP is such fun!).
P.S. Rant about Oracle: What kinds of morons use spaces in their file names AND name a directory "core"? grrrr
This is how I did something similar for Oracle binary files as they contain spaces in their names:
Code:
#!/bin/ksh
# Simple script to change owner of files from original owner to new owner.
# jlightner 23-Aug-2005
#
# Usage: chownit olduid newuid
#
find / -user $1 -fsonly vxfs |awk '{print "\""$0"\""}'|xargs chown -h $2
What I found was I had to escape the quotes with the \ but then quote the escape characters themselves. $0 in awk means "the entire line" so what the abvoe does is send the entire line (file name) with a quote at the beginning and a quote at the end to xargs. All the other quotes in that print statement are just so it will use the escape as an escape rather than a litteral.
(REGEXP is such fun!).
P.S. Rant about Oracle: What kinds of morons use spaces in their file names AND name a directory "core"? grrrr
-print0 delimits the return vals from find with the null char while -0 tells xargs to expect null delimited strings
As far as your awking goes, I will give it a shot. I tried using sed/tr to replace the spaces in my strings with "\ " before but that required the use of echo; perhaps this will meet with more success...
The problem is takes place before the copy command. When find returns a file name with a space, it is in the top of the for loop where it is read as two separate arguments.
You can temporarily change the value of the the IFS variable so that this doesn't happen.
[code]
ifs=$IFS
IFS='\
'
for file in $(find $BASE_DIR -type f -mtime +$AGE); do
cp -p --parent "$file" $BACKUP_DIR && rm "$file" || echo failed to backup "$file"
done
IFS=ifs
It doesn't make sense to me to abort the backup because a single copy failed.
You may still have a problem with certain evil characters, such as "!" which have a special meaning to the shell, and are evaluated in double quotes.
The -0 option isn't available in HP-UX xargs which is where I came up with this script originally. Thanks for the tip though - It may come in handy if I need to do something similar in Linux (as is likely - we're looking at migrating our Oracle Apps tier to Linux from HP-UX).
The -0 option isn't available in HP-UX xargs which is where I came up with this script originally. Thanks for the tip though - It may come in handy if I need to do something similar in Linux (as is likely - we're looking at migrating our Oracle Apps tier to Linux from HP-UX).
The problem is takes place before the copy command. When find returns a file name with a space, it is in the top of the for loop where it is read as two separate arguments.
You can temporarily change the value of the the IFS variable so that this doesn't happen.
[code]
ifs=$IFS
IFS='\
'
for file in $(find $BASE_DIR -type f -mtime +$AGE); do
cp -p --parent "$file" $BACKUP_DIR && rm "$file" || echo failed to backup "$file"
done
IFS=ifs
So, if this works, do you prefer prayer or hymns?
Quote:
Originally Posted by jschiwal
It doesn't make sense to me to abort the backup because a single copy failed.
Yeah, except that I am writing this knowing that people that know nothing about the script will be running it. It is not critical if we miss a file, but it could be a bad thing under certain circumstances; "side-effects = bad". I'd rather it puke and have the know-nots call the know-whats because they can't proceed. Nothing ticks me off more than asking someone, "So, after the script ran, did you read the log file for failures?" The response is always, "Well, no... the script completed just fine". *sigh*
Quote:
Originally Posted by jschiwal
You may still have a problem with certain evil characters, such as "!" which have a special meaning to the shell, and are evaluated in double quotes.
Thanks, that is a good warning; I'll do some testing for the different use cases.
Of course although I put mine in a script to be used later and commented it and put in the shell interpreter my original solution really was one line also.
I'll admit it had a few more characters than the above line though.
On the plus side the OP didn't have to wait nearly a year for my answer.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.