Home > Software engineering >  Function output redirection to file doesn't work in shell script
Function output redirection to file doesn't work in shell script

Time:01-24

I have written a basic shell script which takes in log*.zip (as downloaded from GitHub actions), greps all matching lines in specific files, and outputs the matched lines in a tabular form. Here is (relevant) part of the source code:-

#!/bin/bash
....
    FILENAME=$1
    shift

    OUT_FN=$1
    shift

    PATTERN=$@
....

function print_content {
    LINE_LENGTH=130
    LINE_LENGTH_PRINTF_FORMAT_FILENAME=$(($LINE_LENGTH-3)) # to save calculations in loop

    for file in ./*; do
        MATCHING_LINES=$(grep -n $PATTERN "$file" | cut -f1 -d:)
        [ -z "$MATCHING_LINES" ] && continue

        LONGEST_ML=$(wc -L <<< "$MATCHING_LINES")
        LINE_LENGTH_PRINTF_FORMAT_LINE=$(($LINE_LENGTH-$LONGEST_ML-7))
        PRINTF_FORMAT="| %-"$LONGEST_ML"s | %-"$LINE_LENGTH_PRINTF_FORMAT_LINE"s |\n"

        perl -E 'say "-" x '"$LINE_LENGTH"
        printf "| %-"$LINE_LENGTH_PRINTF_FORMAT_FILENAME"s|\n" "$file"
        perl -E 'say "-" x '"$LINE_LENGTH"

        while IFS= read -r line; do
            LINE_DATA=$(sed "$line"'q;d' $file | ansifilter | tr -d $'\r')
            LINE_DATA=${LINE_DATA#*Z}
            LINE_DATA=$(sed 's/^[ \t]*//;s/[ \t]*$//' <<< "$LINE_DATA")

            printf "$PRINTF_FORMAT" "$line" "${LINE_DATA:0:$LINE_LENGTH_PRINTF_FORMAT_LINE}"

            for (( i=$LINE_LENGTH_PRINTF_FORMAT_LINE; i < ${#LINE_DATA}; i=$(($i $LINE_LENGTH_PRINTF_FORMAT_LINE)) )); do
                printf "$PRINTF_FORMAT" " " "${LINE_DATA:$i:$LINE_LENGTH_PRINTF_FORMAT_LINE}"
            done
        done <<< "$MATCHING_LINES"

        perl -E 'say "-" x '"$LINE_LENGTH"
        echo
    done
}

LOG_DIR="build  build"

unzip $FILENAME "$LOG_DIR"'/*' >/dev/null 2>&1

cd "$LOG_DIR"
....
print_content > "$OUT_FN"

echo "Output saved to file '$OUT_FN'"

cd ..
rm -r "$LOG_DIR"

Actually, the script doesn't change the contents of $OUT_FN. I have tried setting the contents of file named test-grepped.log and then running this script, giving output file name as test-grepped.log. I checked the contents of the test file both before and after running the script, and they both are same.

When I change

print_content > "$OUT_FN"

to

print_content

and run the script, I get this result (the expected result) in terminal (Unpacking debconf is passed as pattern):

----------------------------------------------------------------------------------------------------------------------------------
| ./3builddistro                                                                                                                 |
----------------------------------------------------------------------------------------------------------------------------------
| 90197 | I: Unpacking debconf...                                                                                                |
----------------------------------------------------------------------------------------------------------------------------------

Output saved to file 'test-grepped.log'

This confirms that function print_content works fine, but redirecting its output to file $OUT_FN doesn't work. Redirecting the whole script's output also works as expected. But I wanted that my script itself redirects output to file, instead of doing ./my-script.sh ... > output.log everytime.

What is the error in my script?

Please help.

Thanks

CodePudding user response:

As @user1934428 commented, I had cd'd to $LOG_DIR, and then created $OUT_FN relative to that dir. Due to this, redirecting to $OUT_FN resulted in making a file in $LOG_DIR, which I later on deleted by rm -r $LOG_DIR.

I resolved this issue by cding to $LOG_DIR inside the function print_content only, and later on in the function itself, cding to ...

  • Related