DarkerIvy
DarkerIvy

Reputation: 1587

Why does read throw an error in bash but works fine?

This bash script writes an array to a file and then reads the file back into a different array. (This is useful for array-based communication between scripts.) However, a strange, non-reported error is trapped by the IFS line (line 12). Why?

#!/bin/bash

# eso-error-ic

trap 'echo Error trapped, with code $?, on line ${LINENO}' ERR

# write data to a file
arr=(0 abc) && printf "%s\n" "${arr[@]}" > eso.out

# read data from the file into an array
# throws an error!!
IFS=$'\n' read -d '' -a new_arr < eso.out

# but it worked...
echo ${new_arr[0]}
echo ${new_arr[1]}

Script output:

Error trapped, with code 1, on line 12
0
abc

What's missing is any sort of message displayed when the error is produced. All you get is the message from the trap but no message about what the error is.

In other words, the IFS/read line produces an error, which is trapped, but no error message is displayed and the line properly reads the file into an array variable. It works, reports no error, but an "error" is trapped.

If you comment out the trap line OR switch to the command/eval/cat approach to reading a file into an array (as suggested here), no error is trapped. Here is what the command/eval/cat line would look like for this script (to replace line 12):

IFS=$'\n' GLOBIGNORE='*' command eval 'new_arr=($(cat eso.out))'

Upvotes: 4

Views: 1580

Answers (1)

tripleee
tripleee

Reputation: 189397

The error comes from not receiving the delimiter that read was expecting. I get the same with

read -d x variable <<<"hello"

If I change the input to "hellox" the error disappears.

As mentioned by @Aserre, a detailed analys is at our Unix & Linux sister site and as pointed out by @CharlesDuffy a common workaround is

read variable || [[ $variable ]]

which is used even without -d to cope with files which might lack the final terminating newline.

Upvotes: 7

Related Questions