Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I've got two directories.

/application/inbox
/application/unresponsive

The application looks for *.txt files in the inbox and works with them. Periodically the application will save entries from these files into date-named (2009-07-31) files in the unresponsive folder.

I'd like to setup a cron job which works once a day to move the oldest file from the unresponsive box into the inbox, adding a *.txt extension so it's picked up by the application.

share|improve this question
    
I don't believe it will matter what the destination filename is as long as it's a *.txt file and it doesn't overwrite anything else in the inbox, so rather than "adding *.txt" it can generate its' own *.txt filename. Also if I can add the whole thing to the crontab without needing a script file that would be optimal. :) –  joebert Aug 3 '09 at 0:27
    
Maybe -> SuperUser? –  Isaac Waller Aug 3 '09 at 0:59
add comment

2 Answers

up vote 7 down vote accepted

Untested, likely buggy:

#!/bin/sh

# last file in list sorted newest->oldest
OLDEST=$(ls -t /application/unresponsive | tail -1)

# make sure $OLDEST isn't empty string
if [ -n $OLDEST ]; then
    # quote in case of spaces and remove directory name
    mv "$OLDEST" /application/inbox/$(basename "$OLDEST").txt
fi
share|improve this answer
    
Passes my eyeball test. –  womble Aug 2 '09 at 21:47
2  
oh so close. $OLDEST will contain /application/unresponsive/2009-07-31, so your mv will try to save the file to /application/inbox//application/unresponsive/2009-07-31.txt, which will no doubt fail. It should be fairly easy to fix using the bash pattern matching operators, but I can never remember which way they go. –  David Pashley Aug 2 '09 at 23:03
1  
1. use " characters around every usage of the shell variables - you never know when a file is going to have a space character or something equally annoying in it. –  cas Aug 3 '09 at 1:08
2  
2. use basename to get just the base filename without the dir. eg. 'mv "$OLDEST" /application/inbox/$(basename "$OLDEST").txt' –  cas Aug 3 '09 at 1:12
    
Good spots, David and Craig. I'll update my answer. –  markdrayton Aug 3 '09 at 4:24
show 1 more comment

If you want it to work with files with spaces (more robust). You should loop over them and use the -nt (newest based on modified time) or -ot (oldest) comparison operator with a basic min/max algorithm. Here is an example from this excellent BashFAQ:

files=(*) newest=${f[0]}
for f in "${files[@]}"; do
  if [[ $f -nt $newest ]]; then
    newest=$f
  fi
done

So your example would be (untested):

files=(/application/inbox/*) oldest=${f[0]}
for f in "${files[@]}"; do
  if [[ $f -ot $oldest ]]; then
    oldest=$f
  fi
mv "$oldest" /application/unresponsive/
done

Learning how not to use the output of ls is better I think. Here is link to the argument why. But I leave it up to you to decide if that is true or just pseudo-unix-guru nonsense :-)

share|improve this answer
1  
Ah, neat. I'm not a fan of using the output of ls so it's good to see this solution. –  markdrayton Aug 3 '09 at 4:22
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.