[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-bash] How to set IFS temporarily? (along with assignment and a
From: |
Greg Wooledge |
Subject: |
Re: [Help-bash] How to set IFS temporarily? (along with assignment and array initiation) |
Date: |
Mon, 16 Mar 2015 11:35:07 -0400 |
User-agent: |
Mutt/1.4.2.3i |
On Mon, Mar 16, 2015 at 09:40:54AM -0500, Peng Yu wrote:
> I use the following 4 lines to set IFS temporarily. But it uses a
> temporary variable OLD_IFS, which could be used by other accidentally.
> Therefore, this piece of code is not entirely safe.
It also doesn't work correctly if IFS was unset. You will "restore"
IFS to an empty value, instead of unsetting it. The two behave very
differently.
> OLD_IFS="$IFS"
> IFS=$'\n'
> array=($(printf "%s\n" 'a b' 'c d'))
> IFS="$OLD_IFS"
Your array assignment is not safe, and is quite silly. Just do this
instead:
array=('a b' 'c d')
Now, you are probably going to say "But but but but it was just an
example, my real code is like ....". Please show the REAL code
instead, or at least a framework that has the same characteristics
as the real code.
If you are trying to read the output of an arbitrary program into an
array (line by line), do it like this in bash 4.x:
readarray -t array < <(my program)
Or like this in bash 3.1 and up:
array=()
while IFS= read -r line; do
array+=("$line")
done < <(my program)
array+=("$line") # omit if you want to discard trailing incomplete line
Or like this in bash 2 through 3.0:
array=() i=0
while IFS= read -r line; do
array[i++]=("$line")
done < <(my program)
array[i++]=("$line") # omit if you want to discard trailing incomplete line
DO NOT write code like array=($(...)). It will fail in unexpected ways
when you start giving it arbitary inputs. Setting IFS is not enough to
protect you.