0

I am having an issue with the code below where it executes the array and if statement block to check to see if the file is in active use or not. In order to do the debugging, I have run the script with -x and it is missing the value when it compares the two values in [ … ]. I have searched through number of websites to find the answers but have not been able to do so. What would be the problem or fix over here for that block to compare if the file is in active use or not which will going to be deleted?

#!/bin/bash
#---- parameters check----# 
if ( [ "$2" -le "0" ] ) 
then 
  echo 'Invalid number of days...'
  echo ''
  echo 'The number of days must be greater then 0'
  exit 1;
fi

#----variables----#
Days="$2"
timestamp=$(date +%Y%m%d_%H%M%S)
FILEFOLDER="$1"
logfile=~/"log_purge_$timestamp.txt"

#----foldercheck----#
if [ -d $FILEFOLDER ]
then
  echo "File Folder Directory $FILEFOLDER is set." | tee  "$logfile"
else
  echo "File Folder Directory $FILEFOLDER does not exist! Process will   
Exit."
  exit 1;
fi

#----Find if the file is In Use through Array and IF---#

files_check=($(find "$FILEFOLDER" -type f -mtime +"$Days" -print))

for f_c in "${files_check[@]}"
do
    if [ "${f_c}" == "$( lsof | grep "$f_c")" ] 
    then
    echo "$f_c is in use rite now,quiting the process"
    exit 1
fi
done

echo "No file is in Use right now. Safe to remove"

#---Total Number of Files & Purge ---#
files_num=$(find "$FILEFOLDER" -type f -mtime +"$Days"  | wc -l)

echo "Total number of files" $files_num | tee -a  "$logfile" 

find "$FILEFOLDER" -type f -mtime +"$Days" -print | sed "s|$FILEFOLDER||g" | tee -a $logfile

echo "Purging the files now ....."

find "$FILEFOLDER" -type f -mtime +"$Days" -exec rm {} \;`
3
  • 2
    Remove the () around [ "$2" -le "0" ] Commented Sep 3, 2015 at 22:45
  • So technically it should if [ cond1 (exp) cond2] ??? Commented Sep 4, 2015 at 0:00
  • 1
    I guess probably doesn't matter here, it will just run in a subshell which should return the result of the test anyway. But in general yes, just do [ $2 -le 0 ] or (( $2 < 0 )) Commented Sep 4, 2015 at 0:18

1 Answer 1

1

On my machine, lsof produces lines like

LookupVie 75408 jleffler   14r     REG                1,4     129990 1353198 /System/Library/CoreServices/SystemAppearance.bundle/Contents/Resources/AccessibilityVibrantLightAppearance.car

This clearly isn't identical to the file name, so the equality won't work. You might be OK with grep -o (output only the matching text). Even then, if two or more processes have the same file open, you'll get multiple lines of matching output so you won't be equal. You really want to check the status from whether grep finds the file:

if lsof | grep -q -e "$f_c"
then …
fi

Your residual problems are whether the file names you're checking can ever contain spaces or newlines, etc, or whether the names you're checking can ever be embedded as part of another name. In that case, you need a more complex regular expression (maybe as simple as adding a dollar at the end and a space before hand):

if lsof | grep -q -e "[[:space:]]$f_c$"

The spaces or newlines in the names will mess up the use of file_check=($(find …)).

Also, lsof is fairly expensive. You might do better running it once and capturing the result. You are faced with TOCTOU (time of check, time of use) issues anyway — the file may not have been in use when the script looked, but may now be in use, or vice versa (the file was in use when checked, but the file is no longer in use).

Sign up to request clarification or add additional context in comments.

2 Comments

so what would be the best way to check to see if the file is in USE or not for this script through bash ?
tmp=$(mktemp "${TMPDIR:-/tmp}/litmus.XXXXXX"); trap "rm -f '$tmp'; exit 1" 0 1 2 3 13 15; lsof > "$tmp" before your loop; then if grep -q -e "$f_c" $tmp; then …file in use…; fi and finally rm -f "$tmp"; trap 0 to remove the temporary file and exit successfully. Earlier exits will report an exit status of 1, failure, because of the first trap. All of which is standard shell scripting stuff for robust programming. You can futz with the location of the temporary file if you don't like using /tmp by accident — create a protected sub-directory and put the file in that, or other means.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.