Search code examples
bashshposix

POSIX alternative to multiple variables assignments with read


In bash (works on v4 at least), the following commands allow to assign multiple variables from a string :

IFS=',' read a b <<< "s1,s2"

IFS=',' read a b < <(echo "s1,s2") # an equivalent

After one of these commands :

$ echo $a
s1
$ echo $b
s2

But provided commands are not POSIX-compliant; if run in sh (dash) :

sh: 1: Syntax error: redirection unexpected

What is a POSIX-compliant alternative to those commands? I tried :

IFS=',' echo "s1,s2" | read a b

The command succeeds (return code 0), but echo $a and echo $b then prints nothing.


Solution

  • a and b are set, but due to the pipline, the read command runs in a subshell. When the subshell exits, the variables disappear.

    You can read from a here-doc

    IFS=, read a b <<END
    s1,s2
    END
    

    To replace any arbitrary pipeline (or process substitution), you can capture the pipeline's output and put that variable in a heredoc:

    output=$( seq 10 20 | paste -sd, )
    IFS=, read a b <<END
    $output
    END
    echo "$a"
    echo "$b"
    

    outputs

    10
    11,12,13,14,15,16,17,18,19,20