edition
edition

Reputation: 678

Collecting data from a UNIX program with Bash Redirection

I am attempting to write a script that outputs a CSV file (specified by the user), from the temperature value given by the acpi program. Each data entry is appended to the CSV file, every second (for now).

I have two issues that need to be resolved in my script:

To fix the errors in the script (such as the file access error on line 14), and to allow the user to specify the time delay.

Here's the bash script:

#!/bin/bash

# This script monitors the CPU temperature (in degrees C) over time, and
# records the data to a CSV file.

# Written by Ben Cottrell

function start_log()
{
    touch "$output_csv"
    if hash acpi 2>/dev/null; then
        echo -e "time,temperature\n" > "$output_csv"
        while (true); do
            sleep 1
            echo -e "$(date +%T),$(acpi -t | awk '{print $4}')\n" >> "$output_csv"
        done
    else
        echo "Error: acpi is not installed. Please execute \"sudo apt-get install acpi, before running this script.\""
    fi
}

if [ "$1" ]; then
    local output_csv = $1
    start_log
else
    echo -e "Error: No filename specified.\n"
fi

echo -e "\n"

Upvotes: 3

Views: 83

Answers (2)

tripleee
tripleee

Reputation: 189679

Here's a rewrite with the worst errors and idiom violations fixed.

#!/bin/bash

function start_log()
{
    local output_csv=$1
    local delay=$2
    if hash acpi 2>/dev/null; then
        echo "time,temperature" > "$output_csv"
        while true; do
            sleep "$delay"
            echo "$(date +%T),$(acpi -t | awk '{print $4}')"
        done >>"$output_csv"
    else
        cat <<________error >&2
$0: Error: acpi is not installed.
 Please execute \"sudo apt-get install acpi\" before running this script.
________error
        exit 2
    fi
}

delay=1  # default to 1 sec delay
while true; do
    case $1 in
      -t) shift; delay=$1; shift;;   # Maybe validate the value of $delay
      -*) echo "$0: Unknown option: '$1'" >&2; exit 1;;
      *)  break;;
    esac
done

if [ "$1" ]; then
    start_log "$1" "$delay"
else
    echo "$0: Error: No filename specified." >&2
    exit 1
fi

Including the program name in error messages is useful when it is being invoked from another script, which might get invoked from another script, etc.

Notice how the redirection is only done once, after the loop, instead of repeatedly inside the main loop.

Notice also how the function receives its parameters from the caller, instead of pulling in global variables.

Hand-crafting the option parsing is hardly more complex than doing it "properly" with getopts for simple processing.

Upvotes: 1

Sriharsha Kalluru
Sriharsha Kalluru

Reputation: 1823

Try this.

#!/bin/bash

# This script monitors the CPU temperature (in degrees C) over time, and
# records the data to a CSV file.

# Written by Ben Cottrell

function start_log()
{
    touch "$output_csv"
    read -p 'Enter the time interval for collecting data in seconds: ' t
    if hash acpi 2>/dev/null; then
        echo -e "time,temperature\n" > "$output_csv"
        while (true); do
            sleep $t
            echo -e "$(date +%T),$(acpi -t | awk '{print $4}')\n" >> "$output_csv"
        done
    else
        echo "Error: acpi is not installed. Please execute \"sudo apt-get install acpi, before running this script.\""
    fi
}

if [ -n "$1" ]; then
    local output_csv = $1
    start_log
else
    echo -e "Error: No filename specified.\n"
fi

echo -e "\n"

Upvotes: 0

Related Questions