On 5/16/2017 10:33 AM, Kenny McCormack wrote:
> In article <off1t5$m2e$
1...@news-1.m-online.net>,
> Janis Papanagnou <
janis_pa...@hotmail.com> wrote:
> ...
>> (Note that because 'set' is a special builtin where the environment
>> for the command can't be set directly. (Frankly, I don't know why it
>> can't be handled consistently but that's what we have to live with.)
>> Have you tried putting the IFS=... on a separate line as I suggested?
>
> I hadn't, but, yes, this works:
>
> $ IFS=$'\n';set -- $(history);echo $#
> 500
> $
>
> Of course, what's messy about that is you now have to deal with
> saving/restoring the old IFS value (the above leaves IFS set to just
> newline). The good news, though, is that this doesn't break your shell
> like it did in the old days.
>
> It's weird, though, because I'm pretty sure that I've seen code like that
> (without the semicolon before the 'set') in posts and stuff, but now it
> seems like that can't be right. Oh well...
>
IFS=$'\n' command
makes the value of IFS (or any other variable set on the command line) available
in the environment **during the execution of command**. It does not make it
available during parameter expansion for command so in particular it's not
available when command is "set -- parameters".
Use this instead:
$ IFS=$'\n' read -r -d '' -a arr < <(printf '1 2\n3\n' && printf '\0'); declare
-p arr
declare -a arr=([0]="1 2" [1]="3")
and if you MUST set positional parameters after that (can't imagine why you
wouldn't just use the array though) then set them from the array contents:
$ set -- "${arr[@]}"; echo "$#: $1, $2"
2: 1 2, 3
Replace "printf '1 2\n3\n'" with "history" or whatever command you like of course.
Regards,
Ed.