Can I use read to read content of a variable

Can I use the read command to read the contents of a variable? I'm trying by using the following code and getting nothing back. I'm in a Linux environment.

#!/bin/ksh
IFS=~
VAR1=1~2~3~4
echo $VAR1 | read a b c d
print "$a $b $c $d"

this is working for me!!!

fnsonlu1-/home/fnsonlu1> cat v
IFS="~"
var="1~2~3~4"
echo "$var"|read -r a b c d
echo $a"\n"$b"\n"$c"\n"$d
fnsonlu1-/home/fnsonlu1> v
1
2
3
4

You need to quote the ~ in the IFS assignment

IFS="~"

In Bash or Dash you need to group the commands following the pipe.

#!/bin/sh
IFS="~"
VAR1=1~2~3~4
echo $VAR1 | { read a b c d; echo "$a $b $c $d"; }

mjd_tech : I tried both sets of replies and yours worked...except I could not reference the new variables outside of the brackets. In other words I got the values echoed for a,b,c and d from the echo within the brackets, but when I added the second echo line, I had lost the reference....do I need to do an eval or something to make it global?

IFS="~"
VAR1=1~2~3~4
echo $VAR1 | { read a b c d; echo "$a $b $c $d"; }
echo $a

#!/bin/ksh
VAR1='1~2~3~4'
set -f
set -- $(IFS='~'; echo $VAR1)
set +f
echo "[$1] [$2] [$3] [$4]"

output is:

1 2 3 4
1 2 3 4

Oops, I forgot to quote ALL the vars...

Ksh version:

#!/bin/ksh
IFS="~"
VAR1="1~2~3~4"

echo "$VAR1" | read a b c d
echo "$a $b $c $d"
echo "$a"

# Result
1 2 3 4
1

Bash / Dash version (no pipe, no brackets)

#!/bin/sh
IFS="~"
VAR1="1~2~3~4"

read a b c d <<EOF
$(echo "$VAR1")
EOF
echo "$a $b $c $d"
echo "$a"

# Result
1 2 3 4
1
  • The Bash version works in ksh
  • The ksh version does not work in Bash.

This is because Bash creates a subshell for the last process in a pipeline, in this case the read statement.

Thus, the variables a b c d would only be visible to the subshell. I used brackets in the earlier Bash example to group read and echo commands in the same subshell.

In this example, I used a "here document" to feed the read command, instead of a pipe. Thus, the read command does not happen in a subshell, and the a b c d variables are visible to the rest of the script.

Hopefully this makes sense.

With a couple of exceptions, variables don't need to be quoted when they are assigned, only when they are expanded.

There is an exception; the tilde does need to be quoted or it will expand to the user's home directory.

No need for echo and command substitution:

read a b c d <<EOF
$VAR1

The only shell that doesn't execute the last element of a pipeline in a subshell is ksh; even pdksh executes it in a subshell.

I hardly ever use here documents. I would do this:

IFS='~'
VAR1=1~2~3~4
set -f
set -- $VAR1
a=$1 b=$2 c=$3 d=$4

It works in all shells.

This has all been very helpful....the following is what I ended up with and it works great. I will be using this to parse out array elements that are delimited. Thanks!

#!/bin/ksh
VAR1=A~B~C~D
set $(IFS='~'; echo $VAR1)
echo $1 $2 $3 $4

Resulting in:
A B C D

cfajohnson : I didn't see your reply until after I posted....I really like your solution because it allows me to parse the variable into the variable names that I want.

Here's my solution:
#!/bin/ksh
VAR1=A~B~C~D
read fld1 fld2 fld3 fld4 <<EOF
$(IFS="~"; echo $VAR1)
EOF
echo $fld1 $fld2 $fld3 $fld4