Search code examples
bashloggingfile-descriptorio-redirection

Bash file descriptor and write printf to a file in a while loop


I'm learning bash programming through a book and now I'm learning about opening files and file descriptors but I can't get this code to work(see below), I want to use the file descriptor 4 to write the output of the lower while loop to a file somefile24.log but somefile24.log is empty after I run the code.

Here is the code:

#!/bin/bash
#
# openFile.sh: print the contents of orders.txt

shopt -s -o nounset

declare LINE

exec 3< orders.txt
while read LINE <&3
do
    printf "%s\n" "$LINE"
done


echo
echo "Here is the new part of the program!"


exec 4> somefile24.log
count=1
while read LINE <&3
do
    printf "%s-----count=%d\n" "$LINE" "$count" >&4
    let count++
done
exit 0

Here is the output:

(something78@notemDEB78)-(01:45:03)-(~/Bash_Programming_2018)
$./openFile.sh 
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something
something and something and something

Here is the new part of the program!

Expected output is:

The script writes the contents of orders.txt to somefile24.log


I've tried to check the code in shellcheck but it doesn't see the problem and only gives me this:

$ shellcheck myscript

Line 10:
while read LINE <&3
      ^-- SC2162: read without -r will mangle backslashes.

Line 22:
while read LINE <&3
      ^-- SC2162: read without -r will mangle backslashes.

Line 25:
    let count++
    ^-- SC2219: Instead of 'let expr', prefer (( expr )) .

I've tried to make a test on the command line:

(something78@notemDEB78)-(01:59:41)-(~/Bash_Programming_2018)
$exec 3>somefile24.log 
(something78@notemDEB78)-(01:59:59)-(~/Bash_Programming_2018)
$echo testing >&3
(something78@notemDEB78)-(02:00:03)-(~/Bash_Programming_2018)
$cat somefile24.log 
testing

I know that I can just do:

while
printf "%s\n" "$LINE" >> somefile24.log

QUESTION:

Is it possible to use a file descriptor to write to a file like this in a loop and if so how and what am I doing wrong?

And why is somefile24.log alway's empty after I run the script?


Solution

  • You already read the contents of the file in your first loop. Hence the file descriptor 3 is already at EOF. You can reset the file descriptor 3 before you read on it again. E.g. before your second loop, run this again exec 3< orders.txt