Chinaunix

标题: 重定向的内核实现 [打印本页]

作者: whpu000625    时间: 2017-01-20 15:16
标题: 重定向的内核实现
有哪位知道重定向功能是在内核的什么地方实现的,我现在想调查一个问题,找不到头绪。



作者: jeppeter    时间: 2017-01-20 20:13
回复 1# whpu000625

重定向根本没有内核的代码处理,如果说真的有,就是打开文件,关闭文件。还有就是dup,
对应内核的调用是 sys_open sys_close sys_dup

作者: whpu000625    时间: 2017-01-22 09:39
jeppeter 发表于 2017-01-20 20:13
回复 1# whpu000625

重定向根本没有内核的代码处理,如果说真的有,就是打开文件,关闭文件。还有就是d ...

也就是说如果数据重定向到一个文件中,其实就是打开该文件,写入数据,关闭文件?

作者: nswcfd    时间: 2017-01-22 19:27
2楼正解,本质就是dup/dup2。
作者: whpu000625    时间: 2017-02-10 17:26
有人能解释一下下面的操作的内核流程么
  1. echo test > file
复制代码

作者: Godbach    时间: 2017-02-11 22:35
回复 5# whpu000625
可以用  strace 自己简单跟一下。




作者: whpu000625    时间: 2017-02-12 22:14
回复 6# Godbach

没看到打开file文件的操作,不太明白是怎么把内容写入file中的?
  1. [root@centos6 ~]# strace echo 0 > file
  2. execve("/bin/echo", ["echo", "0"], [/* 23 vars */]) = 0
  3. brk(0)                                  = 0xdb5000
  4. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8995bb9000
  5. access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
  6. open("/etc/ld.so.cache", O_RDONLY)      = 3
  7. fstat(3, {st_mode=S_IFREG|0644, st_size=17666, ...}) = 0
  8. mmap(NULL, 17666, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8995bb4000
  9. close(3)                                = 0
  10. open("/lib64/libc.so.6", O_RDONLY)      = 3
  11. read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\356\1\0\0\0\0\0"..., 832) = 832
  12. fstat(3, {st_mode=S_IFREG|0755, st_size=1921216, ...}) = 0
  13. mmap(NULL, 3750152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8995607000
  14. mprotect(0x7f8995792000, 2093056, PROT_NONE) = 0
  15. mmap(0x7f8995991000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18a000) = 0x7f8995991000
  16. mmap(0x7f8995996000, 18696, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f8995996000
  17. close(3)                                = 0
  18. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8995bb3000
  19. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8995bb2000
  20. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8995bb1000
  21. arch_prctl(ARCH_SET_FS, 0x7f8995bb2700) = 0
  22. mprotect(0x7f8995991000, 16384, PROT_READ) = 0
  23. mprotect(0x7f8995bba000, 4096, PROT_READ) = 0
  24. munmap(0x7f8995bb4000, 17666)           = 0
  25. brk(0)                                  = 0xdb5000
  26. brk(0xdd6000)                           = 0xdd6000
  27. open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
  28. fstat(3, {st_mode=S_IFREG|0644, st_size=99158576, ...}) = 0
  29. mmap(NULL, 99158576, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f898f776000
  30. close(3)                                = 0
  31. fstat(1, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
  32. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8995bb8000
  33. write(1, "0\n", 2)                      = 2
  34. close(1)                                = 0
  35. munmap(0x7f8995bb8000, 4096)            = 0
  36. close(2)                                = 0
  37. exit_group(0)                           = ?
复制代码


作者: Godbach    时间: 2017-02-12 23:22
回复 7# whpu000625

write(1, "0\n", 2)

这一行看到了吗。



作者: whpu000625    时间: 2017-02-13 11:04
回复 8# Godbach

这一行是往标准输入里面写,那又是怎么写到file文件的呢?
难道file文件的描述符是1?file文件什么时候被打开的?

作者: Godbach    时间: 2017-02-13 18:46
回复 9# whpu000625

echo 本身是打到标准输出的,然后标准输出被重定向。 你再看下 strace 的选项,有没有显示更详细的信息。


作者: whpu000625    时间: 2017-02-13 21:47
回复 10# Godbach

看了一下strace的参数,没有能够显示更详细内容的。
我现在就是想知道执行"echo 0 > file"后,是如何将0写入到file文件中的。
至少应该有open该文件的系统调用吧,但是用strace却没看到?那么系统是如何做到的呢?

作者: sditmaner    时间: 2017-02-14 12:06
回复 5# whpu000625
作者: whpu000625    时间: 2017-02-14 13:35
回复 12# sditmaner

说什么了?

作者: 咸鱼1988    时间: 2017-02-15 08:56
这个"echo 0 > file"语句是shell执行的,尝试下写个test.sh文件

  1. #!/bin/sh
  2. echo 0 > file
复制代码


然后用strace跟踪这个shell文件的执行
作者: whpu000625    时间: 2017-02-15 10:07
回复 14# 咸鱼1988

  1. execve("./test.sh", ["./test.sh"], [/* 21 vars */]) = 0
  2. brk(0)                                  = 0x1815000
  3. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f65f2392000
  4. access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
  5. open("/etc/ld.so.cache", O_RDONLY)      = 3
  6. fstat(3, {st_mode=S_IFREG|0644, st_size=17666, ...}) = 0
  7. mmap(NULL, 17666, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f65f238d000
  8. close(3)                                = 0
  9. open("/lib64/libtinfo.so.5", O_RDONLY)  = 3
  10. read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\310\0\0\0\0\0\0"..., 832) = 832
  11. fstat(3, {st_mode=S_IFREG|0755, st_size=135896, ...}) = 0
  12. mmap(NULL, 2232320, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f65f1f53000
  13. mprotect(0x7f65f1f70000, 2097152, PROT_NONE) = 0
  14. mmap(0x7f65f2170000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1d000) = 0x7f65f2170000
  15. close(3)                                = 0
  16. open("/lib64/libdl.so.2", O_RDONLY)     = 3
  17. read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\r\0\0\0\0\0\0"..., 832) = 832
  18. fstat(3, {st_mode=S_IFREG|0755, st_size=19536, ...}) = 0
  19. mmap(NULL, 2109696, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f65f1d4f000
  20. mprotect(0x7f65f1d51000, 2097152, PROT_NONE) = 0
  21. mmap(0x7f65f1f51000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f65f1f51000
  22. close(3)                                = 0
  23. open("/lib64/libc.so.6", O_RDONLY)      = 3
  24. read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\356\1\0\0\0\0\0"..., 832) = 832
  25. fstat(3, {st_mode=S_IFREG|0755, st_size=1921216, ...}) = 0
  26. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f65f238c000
  27. mmap(NULL, 3750152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f65f19bb000
  28. mprotect(0x7f65f1b46000, 2093056, PROT_NONE) = 0
  29. mmap(0x7f65f1d45000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18a000) = 0x7f65f1d45000
  30. mmap(0x7f65f1d4a000, 18696, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f65f1d4a000
  31. close(3)                                = 0
  32. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f65f238b000
  33. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f65f238a000
  34. arch_prctl(ARCH_SET_FS, 0x7f65f238b700) = 0
  35. mprotect(0x7f65f1d45000, 16384, PROT_READ) = 0
  36. mprotect(0x7f65f1f51000, 4096, PROT_READ) = 0
  37. mprotect(0x7f65f2393000, 4096, PROT_READ) = 0
  38. munmap(0x7f65f238d000, 17666)           = 0
  39. rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
  40. open("/dev/tty", O_RDWR|O_NONBLOCK)     = 3
  41. close(3)                                = 0
  42. brk(0)                                  = 0x1815000
  43. brk(0x1836000)                          = 0x1836000
  44. open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
  45. fstat(3, {st_mode=S_IFREG|0644, st_size=99158576, ...}) = 0
  46. mmap(NULL, 99158576, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f65ebb2a000
  47. close(3)                                = 0
  48. getuid()                                = 0
  49. getgid()                                = 0
  50. geteuid()                               = 0
  51. getegid()                               = 0
  52. rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
  53. gettimeofday({1487153274, 647747}, NULL) = 0
  54. open("/proc/meminfo", O_RDONLY|O_CLOEXEC) = 3
  55. fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
  56. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f65f2391000
  57. read(3, "MemTotal:        1020076 kB\nMemF"..., 1024) = 1024
  58. close(3)                                = 0
  59. munmap(0x7f65f2391000, 4096)            = 0
  60. rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER, 0x7f65f19ed9a0}, {SIG_DFL, [], 0}, 8) = 0
  61. rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER, 0x7f65f19ed9a0}, {SIG_DFL, [], SA_RESTORER, 0x7f65f19ed9a0}, 8) = 0
  62. rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f65f19ed9a0}, {SIG_DFL, [], 0}, 8) = 0
  63. rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f65f19ed9a0}, {SIG_DFL, [], SA_RESTORER, 0x7f65f19ed9a0}, 8) = 0
  64. rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x7f65f19ed9a0}, {SIG_DFL, [], 0}, 8) = 0
  65. rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x7f65f19ed9a0}, {SIG_DFL, [], SA_RESTORER, 0x7f65f19ed9a0}, 8) = 0
  66. rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
  67. rt_sigaction(SIGQUIT, {SIG_IGN, [], SA_RESTORER, 0x7f65f19ed9a0}, {SIG_DFL, [], SA_RESTORER, 0x7f65f19ed9a0}, 8) = 0
  68. uname({sys="Linux", node="centos6.5-make", ...}) = 0
  69. stat("/root", {st_mode=S_IFDIR|0550, st_size=4096, ...}) = 0
  70. stat(".", {st_mode=S_IFDIR|0550, st_size=4096, ...}) = 0
  71. getpid()                                = 31049
  72. open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 3
  73. fstat(3, {st_mode=S_IFREG|0644, st_size=26060, ...}) = 0
  74. mmap(NULL, 26060, PROT_READ, MAP_SHARED, 3, 0) = 0x7f65f2383000
  75. close(3)                                = 0
  76. getppid()                               = 31048
  77. gettimeofday({1487153274, 649657}, NULL) = 0
  78. getpgrp()                               = 31048
  79. rt_sigaction(SIGCHLD, {0x43f2b0, [], SA_RESTORER, 0x7f65f19ed9a0}, {SIG_DFL, [], SA_RESTORER, 0x7f65f19ed9a0}, 8) = 0
  80. getrlimit(RLIMIT_NPROC, {rlim_cur=7838, rlim_max=7838}) = 0
  81. rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
  82. open("./test.sh", O_RDONLY)             = 3
  83. ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff1d061f40) = -1 ENOTTY (Inappropriate ioctl for device)
  84. lseek(3, 0, SEEK_CUR)                   = 0
  85. read(3, "#!/bin/sh\necho 0 > file\n", 80) = 24
  86. lseek(3, 0, SEEK_SET)                   = 0
  87. getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=4*1024}) = 0
  88. fcntl(255, F_GETFD)                     = -1 EBADF (Bad file descriptor)
  89. dup2(3, 255)                            = 255
  90. close(3)                                = 0
  91. fcntl(255, F_SETFD, FD_CLOEXEC)         = 0
  92. fcntl(255, F_GETFL)                     = 0x8000 (flags O_RDONLY|O_LARGEFILE)
  93. fstat(255, {st_mode=S_IFREG|0755, st_size=24, ...}) = 0
  94. lseek(255, 0, SEEK_CUR)                 = 0
  95. rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
  96. read(255, "#!/bin/sh\necho 0 > file\n", 24) = 24
  97. rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
  98. open("file", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
  99. fcntl(1, F_GETFD)                       = 0
  100. fcntl(1, F_DUPFD, 10)                   = 10
  101. fcntl(1, F_GETFD)                       = 0
  102. fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
  103. dup2(3, 1)                              = 1
  104. close(3)                                = 0
  105. fstat(1, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
  106. mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f65f2391000
  107. write(1, "0\n", 2)                      = 2
  108. dup2(10, 1)                             = 1
  109. fcntl(10, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)
  110. close(10)                               = 0
  111. rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
  112. read(255, "", 24)                       = 0
  113. exit_group(0)                           = ?
复制代码


作者: nswcfd    时间: 2017-02-15 11:17
本帖最后由 nswcfd 于 2017-02-15 11:21 编辑

> 发生在bash层面,在strace执行之前就已经发生了。
strace -e open,dup,dup2,write -f bash -c 'echo > xxx'

有人已经回答过了,请忽略。

作者: nswcfd    时间: 2017-02-15 11:18
本帖最后由 nswcfd 于 2017-02-15 11:19 编辑

=====删除重复发帖=====





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2