加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bash – 读取-N和IFS

发布时间:2020-12-15 22:15:02 所属栏目:安全 来源:网络整理
导读:根据手册页中的“读-N”说明: -N nchars仅在读取完全NCHARS字符后返回,除非遇到EOF或读取超时,忽略任何分隔符 但是,在回答以下命令时: $echo 'a b' | while read -N1 c; do echo "$c"; doneab 空格和换行符都已转换为空字符串,而在命令中: $echo 'a b' |
根据手册页中的“读-N”说明:

-N nchars仅在读取完全NCHARS字符后返回,除非遇到EOF或读取超时,忽略任何分隔符

但是,在回答以下命令时:

$echo 'a b' | while read -N1 c; do echo ">>>$c<<<"; done
>>>a<<<
>>><<<
>>>b<<<
>>><<<

空格和换行符都已转换为空字符串,而在命令中:

$echo 'a b' | while IFS= read -N1 c; do echo ">>>$c<<<"; done
>>>a<<<
>>> <<<
>>>b<<<
>>>
<<<

空格和换行符已正确存储在变量中.

因此,似乎分隔符仍然在“读取”或“同时”命令中有一些处理,我不明白.

我们可以将这些结果与使用“read -n”的结果进行比较,该手册描述为:

-n nchars在读取NCHARS字符后返回而不是等待换行符,但如果在分隔符之前读取的NCHARS字符少于NCHARS字符,则表示分隔符

$echo 'a b' | while read -n1 c; do echo ">>>$c<<<"; done
>>>a<<<
>>><<<
>>>b<<<
>>><<<

$echo 'a b' | while IFS= read -n1 c; do echo ">>>$c<<<"; done
>>>a<<<
>>> <<<
>>>b<<<
>>><<<

解决方法

使用hexdump可以让我们准确地看到构成输出的字符,因此稍微更改一下查询可能会有所帮助:

(1)使用正常的IFS和使用-N选项

$(echo 'a b' | while read -N1 c; do c="$c<"; echo -n "$c"; done | hexdump -C)
00000000  61 3c 3c 62 3c 3c                                 |a<<b<<|
00000006

在第一种情况下,0x0a和空格字符的内置读取返回空字符串,因为字符在默认IFS中,并且在输出中忽略IFS中的字符,原因在cdarke的答案中说明.

(2)空IFS和-N选项

$(IFS=""; echo 'a b' | while read -N1 c; do c="$c<"; echo -n "$c"; done | hexdump -C)
00000000  61 3c 20 3c 62 3c 0a 3c                              |a< <b<.<|
00000008

在这种情况下,read内置函数将匹配echo命令输出的四个字符中的每一个,并且在输出中看到0x0a和一个空格,因为对于空IFS,可以将读取的字符分配给局部变量c.

(3)使用正常的IFS和-n选项

$(echo 'a b' | while read -n1 c; do c="$c<"; echo -n "$c"; done | hexdump -C)
00000000  61 3c 3c 62 3c 3c                                 |a<<b<<|
00000006

这给出了与case(1)相同的输出,虽然语义有点不同:0x0a和空格字符的内置读取返回空字符串,因为(i)这两个字符都在默认的IFS中( ii)在任何情况下,读内置的-n选项都不会传递尾随的0x0a字符

(4)使用空IFS和-n选项

$(IFS=""; echo 'a b' | while read -n1 c; do c="$c<"; echo -n "$c"; done | hexdump -C)
00000000  61 3c 20 3c 62 3c 3c                              |a< <b<<|
00000007

在这里我们观察到-n和-N选项之间的差异:使用-n选项,换行特别由read builtin处理并删除,因此从IFS中排除0x0a没有机会允许它传递给局部变量c.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读