Shell while循环语句中的陷阱

2020-07-26  本文已影响0人  LannisterWF

1.while循环中对变量赋值无效

我们经常使用while来循环读取文件的每一行,并用文件中的数据对变量赋值,典型写法如下


#!/bin/bash

value=0

echo "value=$value"

cat data.txt | while read line

do

    value=$line

done

echo "value=$value"


结果显示两次value打印都是0,循环中的赋值没有起作用。问题出在这种while写法上,cat file |  while read 的意思是:使用 cat 命令查看文件,通过管道将结果传送给包含 read 命令的 while 命令,会每次读取文件中的一行文本,传给read后的参数,参数可以为多个,默认以空格分隔,当文件中没有可读取的文本时,read 命令将以非零状态退出。这就意味着while循环中的程序实际上是在一个子进程中执行的,当前进程通过管道将文件内容传递到子进程。循环体中的value并非是外部定义的value,在循环体中对value赋值自然也不能改变外部value的值。

解决方法是换一种读文件的方法,将循环体放到当前进程中执行。

while read line

do

    value=$line

done < data.txt

echo $value

cat file | while read 是一种很不友好的写法,虽然最常用,但是效果最差。推荐使用以上<data.txt的读文件方法。

2.while循环读取不到文件最后一行

用上述cat | while写法读文件时还可能碰见另一个问题:读不到文件的最后一行。如data.txt文件的内容如下

111

222

333

用上述cat | while写法则可能只会读到222,最后一行333被忽视了。上文已经说到while如果判断没有可读取的文本时就会退出,while判断是否到达文件末尾是识别文件结束符EOF。文件最后一行之后如果没有换行符\n,则read读取最后一行时遇到EOF,循环即终止。此时虽在内存有最后一行,但程序已经没有机会再处理此行内容。

知道原因了就可以解决这个问题,权宜之计是在最后一行的后面再换个行。治标的方法是用dos2unix将文件格式转换为Unix,因为缺少换行符一般是由于Windows文件传到Linux没有转换格式。

dos2unix data.txt

Linux命令行真的是宝藏,功能丰富,用法多样。如果Linux的生态圈能够更发达一点,说不定以后Linux

会是家庭电脑的主流操作系统。

上一篇下一篇

猜你喜欢

热点阅读