Як touch -t працює всередині?


20

Як touch -tкоманда працює саме внутрішньо (я намагався знайти її вихідний код, але не зміг)?

Відповіді:


23

touchвикликає utimesсистемний виклик, щоб встановити час модифікації файлу та його час доступу. У деяких системах він замість utimesцього відкриває файл, а потім встановлює час файлу через дескриптор, наприклад, utimensatпід Linux.

Ви можете побачити, як touchпрацює ваша система, переглянувши системні виклики, які вона робить. Під Linux використовуйте strace , наприклад strace touch -d '1 hour ago' foo.

Де знайти вихідний код, залежить від вашої операційної системи. Версія GNU знаходиться в coreutils , є версія в головному дереві джерел будь-якого BSD, є версія в BusyBox , у Minix тощо.


28

Іноді вихідний код вам навіть не потрібен. Використовуйте strace.

$ strace touch -t 201212121212 foobar
execve("/usr/bin/touch", ["touch", "-t", "201212121212", "foobar"], [/* 61 vars */]) = 0
[...] lots of noise [...]
open("foobar", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
dup2(3, 0)                              = 0
close(3)                                = 0
utimensat(0, NULL, {{1355310720, 0}, {1355310720, 0}}, 0) = 0
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

Чому привіт там utimensat(). Що ти?

$ man utimensat

NAME
   utimensat, futimens - change file timestamps with nanosecond precision

Отже, є функція, яка змінює часові позначки файлів і touchвикористовує її для оновлення часової мітки файлу. І ось як це працює всередині.


10

Ось як це працює на Solaris. trussвикористовується замість straceчого тут зовсім інша команда.

Як у Gnu / Linux, utimensatчи використовується системний виклик.

$ truss -vall -u a.out -f touch -t 1306080000 z
4160:   execve("/usr/bin/touch", 0xF0770FC0, 0xF0770FD4)  argc = 4
...
4160/1@1:       -> main(0x4, 0xf0770fc0, 0xf0770fd4, 0xf0770f7c)
...
4160/1@1:           -> atoi_for2(0xf0771131, 0x0, 0x24, 0xebc95be0)
4160/1@1:           <- atoi_for2() = 13
4160/1@1:           -> atoi_for2(0xf0771133, 0x0, 0x24, 0xebc95be0)
4160/1@1:           <- atoi_for2() = 6
4160/1@1:           -> atoi_for2(0xf0771135, 0x0, 0x24, 0xebc95be0)
4160/1@1:           <- atoi_for2() = 8
4160/1@1:           -> atoi_for2(0xf0771137, 0x0, 0x24, 0xebc95be0)
4160/1@1:           <- atoi_for2() = 0
4160/1@1:           -> atoi_for2(0xf0771139, 0x0, 0x24, 0xebc95be0)
4160/1@1:           <- atoi_for2() = 0
4160/1@1:         <- parse_time() = 0x51b257e0
4160/1:         stat64("z", 0xF0770ED0)                         = 0
4160/1:             d=0x08A00002 i=75783706 m=0100644 l=1  u=100   g=10    sz=0
4160/1:                 at = Jun  8 01:48:08 CEST 2013  [ 1370648888.022270973 ]
4160/1:                 mt = Jun  8 01:48:08 CEST 2013  [ 1370648888.022270973 ]
4160/1:                 ct = Jun  8 01:48:08 CEST 2013  [ 1370648888.022273810 ]
4160/1:             bsz=4096  blks=0     fs=tmpfs
4160/1:         utimensat(AT_FDCWD, "z", 0xF0770F60, 0)         = 0
4160/1:                 at = Jun  8 00:00:00 CEST 2013  [ 1370642400.000000000 ]
4160/1:                 mt = Jun  8 00:00:00 CEST 2013  [ 1370642400.000000000 ]
4160/1@1:       <- main() = 0
4160/1@1:       -> _fini()
4160/1@1:       <- _fini() = 0xebcc0140
4160/1:         _exit(0)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.