Jack Arnold
Jack Arnold

Reputation: 75

Bash script failing to create files using array items as filenames

I'm trying to write a script which will read the sizes of certain files and track the growth over time. The way I'm tackling this is by building an array of file names, then generating log files using arrays which are unique to each file I'm wanting to track.

Previously the script was failing here due to me forgetting to call the function written earlier. Oops.

echo "$currentsize" >> "$historic" 

and

oldsize=$(sed 'x;$!d' < "$historic") 

as it wasn't creating the files i'd asked it to create with this loop (because I forgot to call it)

historicdata[$i]="$HOME/ers/test/$i"historic                      
        for historic in "${historicdata[@]}" ; do
            # Creates the file if it does not exist.
            if [ -f "$historic" ]                                               
            then
            :
            else
                touch "$historic"
            fi

Now I'm getting no output whatsoever from the script - No files created and no errors/failures.

Current version of the script is below

#!/bin/bash

# Sets array of files to be monitored
declare -A monitor                                                              
        monitor["erslog"]="$HOME/ers/test/file1.log"
        monitor["sigmalog"]="$HOME/ers/test/file2.log"
        monitor["someotherlog"]="$HOME/ers/test/file3.log"

# Function to set variables to be read/written later on
set_variables () {                                                                    
    for i in "${!monitor[@]}"    
    do
        #This file is watched by appmanager for alerting
        alertfile[$i]="$HOME/ers/test/output/$i"                                

        for alert in "${alertfile[@]}" ; do
            # Creates alert log file if it does not exist
            if [ -f "$alert" ]                
            then
               :
            else
                touch "$alert"
            fi
        done
        # This file logs all historic file size readings
        historicdata[$i]="$HOME/ers/test/$i"historic                      
        for historic in "${historicdata[@]}" ; do
            # Creates the file if it does not exist.
            if [ -f "$historic" ]                                               
            then
            :
            else
                touch "$historic"
            fi
        done
    done
}

# Performs actions for each item in the array
for i in "${monitor[@]}"                                                        
do
set_variables    
    # Scans the file you wish to monitor and sets variable to the file size in bytes.
    currentsize=$(stat '-c%s' "$i")                                              

     # Appends the current file size to the end of whatever is set as the $output file
    echo "$currentsize" >> "$historic"                                 

    # Sets the previous reading as "oldsize" by pulling the second to last line of $historicdata
    oldsize=$(sed 'x;$!d' < "$historic")   
    # This is the difference in size between the current and previous readings.                                     
    difference=$((currentsize - oldsize))                                           

    # Exits the script if there have been no changes. This prevents irrelevant data being written
    if [[ $difference = "0" ]]
    then                                                                    
        exit 1
    # Checks the file size difference (bytes), if greater than 20971519 write an error.
    elif [[ $difference -gt "20971519" ]]                                           
    then
        echo "Previous_Size=$oldsize" > "$alert"
        echo "Current_Size=$currentsize" >> "$alert"
        echo "Difference=$difference" >> "$alert"
        # Alert=1 will activate the AppManager alert
        echo "Alert=1" >> "$alert"         
    else
        echo "Previous_Size=$oldsize" > "$alert"
        echo "Current_Size=$currentsize" >> "$alert"
        echo "Difference=$difference" >> "$alert"
        # Alert=0 will clear the error
        echo "Alert=0" >> "$alert"                                          
    fi
done

Am I even going about this in a logical way? Or is there some better way I could be doing this? Thanks

Upvotes: 1

Views: 60

Answers (1)

Socowi
Socowi

Reputation: 27235

Short answer: The function set_variables is never executed.

You wrote that these two lines cause problems:

echo "$currentsize" >> "$historic"
oldsize=$(sed 'x;$!d' < "$historic")

As it seems, you never set the variable $historc to any value. The only place where $historc may be assigned a value is inside the function set_variables. That function is never executed. The string set_variables appears only once in your script, that is in the function definition.

You can verify that $historic is unset by executing the script with set -x or inserting an echo "historic has value '$historic'" before the problematic lines in your script.

On my system, a redirect to the empty string/path causes the following error:

echo test > "$unsetVariable"
# output:
# bash: : No such file or directory

Same goes for ... < $unsetVariable.

If you have the same error, try to assign a value to historic.

By the way

You don't have to use a six line if else block to create a file if it does not already exist. printf "" >> "$file" does the same trick (and yes, the content and file access time of existing files is preserved).

Upvotes: 2

Related Questions