输入重定向疑惑,请各位指点。

sh/bash/dash/ksh/zsh等Shell脚本
回复
ztf
帖子: 44
注册时间: 2007-04-29 13:15

输入重定向疑惑,请各位指点。

#1

帖子 ztf » 2010-10-15 23:39

#!/bin/sh
exec 4<&0 0<readfile
read line1
read line2
exec 0<&4
echo $line1
echo $line2

上面的脚本,在readfile重定向到0描述符前,为什么需要4<&0。如果不这么做,有什么缺陷?
注:下面的脚本输出的结果也一样。

#!/bin/sh
exec 0<readfile
read line1
read line2
echo $line1
echo $line2
delectate
帖子: 18311
注册时间: 2008-01-09 22:41

Re: 输入重定向疑惑,请各位指点。

#2

帖子 delectate » 2010-10-15 23:48

exec 4<&0 0< name.txt 执行了两个「动作」: 首先, 把文件描述符 0 (标准输入 stdin,一般指键盘) 复制 (duplicate) 到描述符 4 (效果上是把 0 做了个备份), 然后, 用描述符 0 打开 stock.txt.这个时候 stdin 就从 stock.txt 读数据了, 因此后面的 read 就是 name.txt.
--
exec 0<&4 把前面备份的描述符 4 复制回 0, 其实就是恢复了从键盘读数据

如果将上面的 exec 0<&4 换成 exec 0<&4- , 这不但恢复了 stdin, 而且还把临时使用的描述符 4 给 close 掉了

http://www.groad.net/bbs/simple/?t482.html
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 输入重定向疑惑,请各位指点。

#3

帖子 astolia » 2010-10-17 2:17

我觉得是为了防止脚本在shell下使用source方式调用对原文件描述符造成破坏

比如脚本是a.sh,那么用下面的方式

代码: 全选

sh a.sh
或者给a.sh加上可执行权限后

代码: 全选

./a.sh
这两种方式都会新建一个子shell,在子shell中执行,对文件描述符的修改不会影响到父shell,但是,如果用

代码: 全选

source a.sh

代码: 全选

. a.sh
这种方式,会直接在当前shell中执行,脚本运行完毕后,对文件描述符的修改仍然保留,shell会继续从readfile中读取内容当成命令执行。

所以为了安全起见,就要先备份,用完后再恢复
回复