Created
May 11, 2010 16:13
-
-
Save zach-klippenstein/397489 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Run periodically by cron, and will unarchive data in the | |
# ~/auto_unarchive/drop_target directory. | |
# Where the action happens | |
unarchiveDir="~/auto_unarchive/drop_target" | |
# Time in seconds between checking for new archives | |
checkInterval=1.5 | |
# Total number of seconds the script should run for before | |
# exiting. | |
runTime=59 | |
# If non-empty, some extra messages will be logged. | |
# This should be off for long-term cron use, as it will bloat | |
# the logs. | |
verbose="" | |
# Flag used to log when killed. | |
cleanExit="" | |
# Will only run if this file doesn't exist | |
lockFile="$unarchiveDir/.unarchive.lock" | |
# Hash table of archive types to their extraction commands. | |
# The keys are used to grep the output of the file command. | |
# Used by: getNextArchive, | |
extractKeys[0]=Zip; extractCmds[0]="unzip" | |
extractKeys[1]=gzip; extractCmds[1]="gunzip" | |
function printUsage() | |
{ | |
local scr="`basename $0`" | |
echo "usage: $scr [--help | -h]" | |
} | |
# Create the unarchive dir if necessary, and return true iff it | |
# exists. | |
function setupDir() | |
{ | |
local targetDir="$1" | |
if [ ! -d "$targetDir" ]; then | |
log "Creating auto unarchive directory: $targetDir" <(mkdir "$targetDir") | |
fi | |
if [ -d "$targetDir" ]; then | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
# Returns true only if this instance of the script currently | |
# owns the lock on the unarchiving directory | |
function tryLock() | |
{ | |
if [ ! -f "$lockFile" ]; then | |
echo "$$" >"$lockFile" | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
# Releases the lock on the unarchiving directory if this script | |
# currently holds it | |
function unlock() | |
{ | |
# If this instance of the script currently owns the lock | |
if [ $$ = "$(cat "$lockFile" 2>/dev/null)" ]; then | |
rm -f "$lockFile" | |
return 0 | |
fi | |
return 1 | |
} | |
# Prints the index of the extract key/command for a file. | |
# $1 - the filename whose type to search for | |
function findExtractIndex() | |
{ | |
fileName="$1" | |
i=${#extractKeys[*]} | |
i=$(($i - 1)) | |
if [ "$fileName" ]; then | |
while [ $i -ge 0 ]; do | |
key="${extractKeys[$i]}" | |
if [ "$(file "$line" | grep "$key")" ]; then | |
echo $i | |
return 0 | |
fi | |
i=$(($i - 1)) | |
done | |
fi | |
return 1 | |
} | |
# Prints the absolute path of a relative path, relative to the | |
# current directory. | |
# $1 - the path to make absolute | |
function absolutePath() | |
{ | |
path="$1" | |
if [ "$1" ]; then | |
# Clean leading ./ (e.g. from find command output) | |
if [ './' = "${path:0:2}" ]; then | |
path="${path:2}" | |
fi | |
# Prepend working dir onto non-absolute paths | |
if [ '/' != "${path:0:1}" ]; then | |
echo "$(pwd)/$path" | |
else | |
echo "$path" | |
fi | |
fi | |
} | |
# Prints the extract command for a file, ready-to-run. | |
# $1 - the file to get the extract command for | |
# $2 - (optional) the index in the extract table. If not | |
# specified, will search the table. | |
function getExtractCmd() | |
{ | |
fileName="$(absolutePath "$1")" | |
index="$2" | |
[ -z "$index" ] && index="$(findExtractIndex "$fileName")" | |
if [ "$index" ]; then | |
# Construct the runnable command and return true | |
echo "${extractCmds[$index]} '$fileName'" | |
return 0 | |
fi | |
return 1 | |
} | |
# Prints the name of an archive in the current directory, | |
# or nothing if there are no archives. | |
# If there is an archive, prints the index in the extract | |
# table on the second line. | |
function getNextArchive() | |
{ | |
find . -maxdepth 1 -type f | while read line; do | |
index="$(findExtractIndex "$line")" | |
if [ "$index" ]; then | |
echo "$line" | |
echo $index | |
return 0 | |
fi | |
done | |
return 1 | |
} | |
# Extracts a file into directory above unarchive directory. | |
# $1 - filename of archive | |
# $2 - (optional) index in extract table | |
function extractFile() | |
{ | |
fileName="$1" | |
index="$2" | |
[ -z "$index" ] && index="$(findExtractIndex "$fileName")" | |
cmd="$(getExtractCmd "$curFile" "$index")" | |
# Perform the extract and capture the output | |
extractLog="$( ( | |
cd .. | |
echo "Changed to directory '$(pwd)'." | |
eval $cmd | |
) 2>&1)" | |
extractResult=$? | |
# Log the output | |
echo -n "$extractLog" | log "Found archive '$curFile', extracting: $cmd" | |
# log "Found archive '$curFile', extracting: $cmd" | |
# echo "$extractLog" | while read l; do log "$l"; done | |
if [ $extractResult -eq 0 ]; then | |
( | |
[ ! -d "extracted" ] && mkdir extracted | |
mv "$fileName" extracted/ | |
) 2>&1 | log "Extraction successful, deleting '$fileName'..." | |
return 0 | |
else | |
log "Extraction failed." | |
return 1 | |
fi | |
} | |
function exitHandler() | |
{ | |
unlock | |
if [ "$cleanExit" ]; then | |
[ "$verbose" ] && log "Finished monitoring '$unarchiveDir' (ran for $SECONDS seconds), exiting." | |
else | |
log "Killed after $SECONDS seconds, aborting monitoring '$unarchiveDir'." | |
fi | |
} | |
# Process user-specified flags | |
while [ "`echo "$1" | grep -E -e '^-.'`" ]; do | |
case "$1" in | |
--help|-h) | |
printUsage | |
exit 0 | |
;; | |
*) | |
printUsage | |
exit 1 | |
;; | |
esac | |
shift | |
done | |
# Make sure directory is unlocked if the script is killed | |
trap "exitHandler" EXIT | |
if setupDir "$unarchiveDir"; then | |
cd "$unarchiveDir" | |
[ "$verbose" ] && log "Monitoring '$unarchiveDir' for $runTime seconds, at $checkInterval intervals..." | |
while [ $SECONDS -le "$runTime" ]; do | |
# Only continue if there are no other instances of | |
# this script running. | |
if tryLock; then | |
# Get the filename and index of the next archive | |
nextArchive="$(getNextArchive)" | |
# Process all archives in the current directory before sleeping | |
while [ "$nextArchive" ]; do | |
curFile="" | |
curIndex="" | |
cmd="" | |
echo "$nextArchive" | ( | |
read line && curFile="$line" | |
read line && curIndex="$line" | |
cmd="$(getExtractCmd "$curFile" $curIndex)" | |
extractFile "$curFile" "$curIndex" | |
) | |
nextArchive="$(getNextArchive)" | |
done | |
unlock | |
fi | |
sleep "$checkInterval" | |
done | |
cleanExit="true" | |
fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Cron entry | |
1 * * * * auto_unarchive |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment