close close FILEHANDLE close
这个函数关闭与 FILEHANDLE 关联的文件,套接字,或者管道。(如果省略参数,那么它关闭当前选定的文件句柄。)如果关闭成功它返回真,否则返回假。如果你准备马上就对 FILEHANDLE 做另外一次 open,那么你用不着关闭它,因为下一次 open 会替你关闭它。(参阅 open)不过,对输入文件的明确的关闭重置行计数器($.),而 open 做的隐含关闭不会做这件事情。
FILEHANDLE 可以是一个表达式,它的值可以用做一个间接的文件句柄(要么是一个真实文件句柄名字,要么是一个指向任何可以解释为一个文件句柄对象的引用。)
如果该文件句柄来自一个管道打开,如果任何下层系统调用失败或者在管道另一端的程序退出值非零,那么 close 将返回假。对于后面一种情况,close 强制 $!($OS_ERROR)为零。所以如果一个在管道上的 close 返回了一个非零值,那么可以检查 $! 的值判断问题来自管道本身(非零值)还是来自管道对端的程序(零值)。不管哪种情况,$?($CHILD_ERROR)都包含与管道另一端的命令相关联的等待状态值(参阅在 system 里它的解释)。比如:
open(OUTPUT, '| sort -rn | lpr -p') # 输出给 sort 和 lpr or die "Can't start sortlpr pipe: $!"; print OUTPUT @lines; # 把内容打印到输出 close OUTPUT # 等待 sort 结束 or warn $! ? "Syserr closing sortlpr pipe: $!" : "Wait status $? from sortlpr pipe";
用 dup(2) (复制)管道的方法制作的文件句柄被当作一个普通的文件句柄,所以在那个文件句柄上的 close 不会等待子进程。不过你关闭最初的文件句柄的时候就必须等待子进程。比如:
open(NETSTAT, "netstat -rn |") or die "can't run netstat: $!"; open(STDIN, "<&NETSTAT") or die "can't dup to stdin: $!";
如果你关闭上面的 STDIN,那么不会有等待发生,但是如果你关闭 NETSTAT,那么就有。
如果你自己打理了一个已退出的管道子进程,那么关闭就会失败。如果你有一个自己的 $SIG{CHLD} 句柄,在管道子进程退出的时候触发,或者你故意在从 open 调用返回的进程 ID 上调用 waitpid,那么就有可能发生关闭失败的情况。