遇到一个在脚本中读取文件内容占用文件句柄的小问题

一般来说,嵌入式设备的程序是上电自动运行的。设备系统启动后会自动运行某些系统级脚本(/ect/rc3.d/下的脚本),最终会运行我们自定义的脚本,在该脚本中会运行应用程序。——这就是系统自动启动的一般做法。

在测试中,发现如果升级在升级程序过程中断电(测试人员故意的,以模拟某些实际可能也许不会发生的事),则设备无法再启动。我们的设备使用硬盘存储系统文件,所谓“升级”,就是把程序文件写到磁盘分区某个目录上。深入了解后,发生写的文件大小全为0,当然是不正确的,程序无法执行,设备启动就不正常了。——根本原因是,恰好有一个自定义的脚本文件size为0,这个文件挂了,后面的过程就无法顺利执行了。后来想到一招。把核心的脚本单独升级,并且保证这个升级一定成功。其后的程序升级则无须升级该核心脚本。

在这个过程中,引发了另一个题目的小问题。虽然前文所述的值得深究,但不是本文重点。

启动脚本会去读一些文件的配置,使用exec的形式。下面的例子是读取bar文件,并判断其值是否为0,为0执行a.out(q.out为死循环,目的是为了a.out不退出)。如下:

########读文件内容
if [  -f bar ]; then

exec 3< bar
read NUM <&3
echo $NUM

# 判断是这样
if [ "X$NUM" = "X0" ]
then
    echo "NUM is 0"
    ./a.out
else
    echo "NUM not 0"
fi

fi

查询一下a.out进程所占用的文件描述符。结果如下:

root@localhost:~# ps -ef | grep a.out
root     12409 12405  0 08:55 pts/0    00:00:00 ../a.out
root     12412 12386  0 08:55 pts/1    00:00:00 grep --color=auto a.out
root@localhost:~# ll /proc/12409/fd  
total 0
dr-x------ 2 root root  0 Jul 27 08:55 ./
dr-xr-xr-x 7 root root  0 Jul 27 08:55 ../
lrwx------ 1 root root 64 Jul 27 08:55 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jul 27 08:55 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jul 27 08:55 2 -> /dev/pts/0
lr-x------ 1 root root 64 Jul 27 08:55 3 -> /mnt/latelee/test/simple_test/shell/bar

我们看到,脚本使用exec 3< bar将bar的内容读取文件描述符3里,由于a.out是一直循环,所以会一直占用着该描述符。

我们看另一个例子,不使用exec,而是直接用cat。如下:

######## 另一种方式
if [  -f bar ]; then

# 只截至第一行的内容
NUM1=`cat bar | head -1`
echo $NUM1

# 判断是这样
if [ "X$NUM1" = "X0" ]
then
    echo "NUM1 is 0"
    ./a.out
else
    echo "NUM1 not 0"
fi

fi

再次看a.out进行的文件描述符,结果如下:

root@localhost:~# ps -ef | grep a.out
root     12418 12414  0 08:56 pts/0    00:00:00 ../a.out
root     12420 12386  0 08:56 pts/1    00:00:00 grep --color=auto a.out
root@localhost:~# ll /proc/12418/fd    
total 0
dr-x------ 2 root root  0 Jul 27 08:56 ./
dr-xr-xr-x 7 root root  0 Jul 27 08:56 ../
lrwx------ 1 root root 64 Jul 27 08:56 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jul 27 08:56 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jul 27 08:56 2 -> /dev/pts/0
root@localhost:~# 

我们看到,脚本已经不占用文件描述符了。

对于这个问题,似乎有点吹毛求疵,但很多时候遇到的问题,往往是小细节引发的,这不得不让我提高敏感度。

文中使用/proc/进程ID/fd目录查看指定进程的文件描述符,这个方法还是比较有用的,下文即将提到。

2015.7.30 李迟



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值