1

I know this question has been asked in different manners, and I've referred to some answers on here to get to where I am now.

I'm trying to create a script to essentially watch a folder and virus scan files once they're not being written to.

The files/strings I need it to handle will sometimes contain spaces and sometimes not, as well sometimes special characters. At the moment it will actually work only on files with spaces in the name (as in actually scan and move them), but not for files without spaces. Also after each file (spaces or not) the while loop breaks thus stopping the script with the following output;

./howscan.sh: line 29: snmp.conf: syntax error: invalid arithmetic operator (error token is ".conf")
./howscan.sh: line 34: snmp.conf: syntax error: invalid arithmetic operator (error token is ".conf")  

I had it working to handle file names without any spaces, but since I introduced the "${files[$i]}" method to use the array elements it only works on files with spaces and outputs the above error.

Feel free to omit the sepscan part of this, as I'm sure if I can get it working with the other tasks it'll work for that too (just wanted to show the full script for a complete understanding).

Current Script:

#!/bin/bash

set -x

workingpath='/mnt/Incoming/ToScan/'
outputpath='/mnt/Incoming/Scanned/'
logfile='/var/log/howscan.log'
faildir='/mnt/Incoming/ScanFailed/'
sepscan='/opt/Symantec/symantec_antivirus/sav manualscan -c'

# Change to working directory
cd $workingpath

# Exclude files with a given extension, in this case .aspx, and declare the remaining files as the array "files"
shopt -s extglob nullglob

# Loop the below - ie it's a watch folder
while true
    do
    # Exclude files with .aspx in the file name
    files=( !(*.aspx) )
    # If the array files is not empty then...
    if [ ${#files[@]} -ne 0 ]; then
        for i in ${files[*]}
        # For every item in the array files process them as follows
        # Declare any variables you wish to happen on files here, not globally
        # Check each file to see if it's in use using fuser, do nothing and log it if its still in use, or process it and log the results
        do
            fileopen=`fuser "${files[$i]}" | wc -c`
            # Here for 'fileopen' we are checking if the file is being writen to.
            if [ $fileopen -ne 0 ]; then
                echo `date` "${files[$i]}" is being used so has been ignored >> $logfile
            else
                echo `date` File "${files[$i]}" not being used or accessed >> $logfile

                    sepscan=`$sepscan "${files[$i]}" | wc -c`
                    if [ $sepscan = 0 ]; then
                        mv "${files[$i]}" $outputpath
                        echo `date` "${files[$i]}" has been virus scanned and moved to $outputpath >> $logfile
                    else 
                        echo `date` "${files[$i]}" has been moved to $faildir as a virus or error was detected >> $logfile
                    fi
            fi
        done
    fi
    echo `date` 'No more files to process. Waiting 60 seconds...' >> $logfile
    sleep 60
done  

Let me know if I can provide anything else to help clarify my issue.

Update:
There is a file in the /mnt/Incoming/ToScan/ directory called snmp.conf by the way.

3
  • 2
    $logfile -> "$logfile" $faildir-> "$faildir" etc. Check you script with shellcheck.net . $sepscan use bash arrays. Do not use ` backticks - use $(...) instead. So you have set -x on top of the script - please show full verbose debug output from execution. Which line is the line 29 and 34? Waiting 60 seconds you might be interested in inotifywait
    – KamilCuk
    Commented Oct 9, 2020 at 12:01
  • I rolled back your latest edit; your question should remain strictly a question. If you want to post an answer of your own, you are more than welcome to do so.
    – tripleee
    Commented Oct 9, 2020 at 12:26
  • Well Choroba really answered this. I don't feel right taking credit for the answer. I was simply trying to share the end result incase anyone else comes across this they might be able to figure it out. If I post an answer does that get accepted as the only answer? Commented Oct 9, 2020 at 12:30

1 Answer 1

1
for i in ${files[*]}

should be

for i in ${!files[*]}
# or
for i in ${!files[@]}

${files[*]} expands to the contents of the array and undergoes word splitting. The above syntax expands to a list of indices of the array.

You might also need to double quote the variables, e.g.

if [ "$fileopen" -ne 0 ]; then
3
  • Thanks for the quick response. I've changed line 24 to for i in "${files[@]}" as well double quoted the $fileopen variable, but still the same response. Also I should add, there's a file in the /mnt/Incoming/ToScan/ directory called snmp.conf at the moment. Commented Oct 9, 2020 at 11:59
  • Oh wait, you want $i to be an index!
    – choroba
    Commented Oct 9, 2020 at 12:04
  • Legend! That's done it! I also had to change the sepscan variable on line 9 to sepscancmd as it was getting messed up on line 36 when trying to call it within itself if you know what I mean. Thanks ever so much! Commented Oct 9, 2020 at 12:15

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