shell - temp IFS as newline only. Why doesn't this work: IFS=$(echo -e '\\n')

﹥>﹥吖頭↗ 提交于 2019-12-04 06:54:02
Digital Trauma

Update - changing my pseudo-comment to a real answer.

I think this answer should explain the behavior you are seeing. Specifically command substitution operators $() and backticks will strip trailing newlines from the command output. However the direct assignment in your second example doesn't do any command subsitution, so works as expected.

So I'm afraid to say I think the upvoted comment you refer to is incorrect.


I think the safest way to restore IFS is to set it in a subshell. All you need to do is put the relevant commands in parentheses ():

(
    IFS=$'\n'
    echo -n "$IFS" | od -t x1
    for file in `printf 'one\ntwo two\nthree'`; do
        echo "Found $file"
    done
)

Of course invoking a subshell incurs a small delay, so performance needs to be considered if this is to be repeated many times.


As an aside, be very careful, filenames can contain both \b and \n. I think just about the only characters they cannot contain are slash and \0. At least thats what it says on this wikipedia article.

$ touch $'12345\b67890'
$ touch "new
> line"
$ ls --show-control-chars
123467890  new
line
$ 

Since newlines are stripped by command substitution, as @DigitalTrauma correctly wrote, you should use a different, POSIX compliant way.

IFS='
'

writes a newline and assign it to it. Simple and effective.

If you don't like assignments that span over two lines, you may use printf as alternative.

IFS="$(printf '\n')"
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!