Câu trả lời:
touch
gọi cuộc gọi utimes
hệ thống để đặt thời gian sửa đổi của tệp và thời gian truy cập của tệp. Trên một số hệ thống, thay vì utimes
, nó sẽ mở tệp và sau đó đặt thời gian tệp thông qua bộ mô tả, ví dụ như với utimensat
Linux.
Bạn có thể thấy cách touch
hoạt động trên hệ thống của mình bằng cách nhìn vào hệ thống mà nó gọi. Trong Linux, sử dụng strace , vd strace touch -d '1 hour ago' foo
.
Nơi tìm mã nguồn phụ thuộc vào hệ điều hành của bạn. Phiên bản GNU nằm trong coreutils , có một phiên bản trong cây nguồn chính của bất kỳ BSD nào, có một phiên bản trong BusyBox , trong Minix , v.v.
Đôi khi bạn thậm chí không cần mã nguồn. Sử dụng 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 +++
Tại sao xin chào utimensat()
,. Bạn là gì
$ man utimensat
NAME
utimensat, futimens - change file timestamps with nanosecond precision
Vì vậy, có một chức năng thay đổi dấu thời gian của tệp và touch
sử dụng nó để cập nhật dấu thời gian của tệp. Và đó là cách nó hoạt động nội bộ.
Đây là cách nó hoạt động trên Solaris. truss
được sử dụng thay vì strace
đó là một lệnh khá khác nhau ở đây.
Giống như trong Gnu / Linux, utimensat
là cuộc gọi hệ thống được sử dụng.
$ 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)