微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Linux proc / pid / fd为stdout是11?

用stdout执行一个脚本,redirect到一个文件。 所以/ proc / $$ / fd / 1应该指向那个文件(因为stdout fileno是1)。 但是,该文件的实际fd是11.请解释,为什么。

这是会议:

$ cat hello.sh #!/bin/sh -e ls -l /proc/$$/fd >&2 $ ./hello.sh > /tmp/1 total 0 lrwx------ 1 nga users 64 May 28 22:05 0 -> /dev/pts/0 lrwx------ 1 nga users 64 May 28 22:05 1 -> /dev/pts/0 lr-x------ 1 nga users 64 May 28 22:05 10 -> /home/me/hello.sh l-wx------ 1 nga users 64 May 28 22:05 11 -> /tmp/1 lrwx------ 1 nga users 64 May 28 22:05 2 -> /dev/pts/0

子代在fork之后写入父文件中创build的文件描述符

文件描述符有什么可能的值?

Windows相当于ulimit -n

IOException:打开的文件过多

如何从PHP调用dup2()系统调用

一个函数调用写入多个文件描述符

处理结束后`/ dev / ttyS *`上的QSerialPort效应?

打开问题 – 太多打开的文件

HANDLE与Linux中的文件描述符类似吗?

中止Linux轮询

我有一个怀疑,但这是高度依赖于你的shell的行为。 你看到的文件描述符是:

0:标准输入

1:标准输出

2:标准错误

10:正在运行的脚本

11:脚本正常标准的备份副本

描述符10和11在exec处于关闭状态,所以不会出现在ls进程中。 然而,0-2是在分叉前准备好的。 我在短划线(Debian Almquist shell)中看到了这种行为,但在bash(Bourne再次shell)中没有。 Bash代替了分叉之后的文件描述符操作,并且顺便使用了255而不是10来代替脚本。 在分叉之后进行更改意味着它不必恢复父级中的描述符,所以它没有从dup2中获得备用副本。

strace的输出可以在这里有所帮助。

相关部分是

fcntl64(1,F_DUPFD,10) = 11 close(1) = 0 fcntl64(11,F_SETFD,FD_CLOEXEC) = 0 dup2(2,1) = 1 stat64("/home/random/bin/ls",0xbf94d5e0) = -1 ENOENT (No such file or +++++++>directory) stat64("/usr/local/bin/ls",0xbf94d5e0) = -1 ENOENT (No such file or directory) stat64("/usr/bin/ls",0xbf94d5e0) = -1 ENOENT (No such file or directory) stat64("/bin/ls",{st_mode=S_IFREG|0755,st_size=96400,...}) = 0 clone(child_stack=0,flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,+++++++>child_tidptr=0xb75a8938) = 22748 wait4(-1,[{WIFEXITED(s) && WEXITSTATUS(s) == 0}],NULL) = 22748 --- SIGCHLD (Child exited) @ 0 (0) --- dup2(11,1) = 1

因此,shell将现有的stdout移动到10(即11)以上的可用文件描述符,然后将现有的stderr移到它自己的stdout(由于>&2重定向),然后当ls命令恢复到它自己的stdout时完成。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐