[unix] touch -t는 내부적으로 어떻게 작동합니까?

touch -t내부적으로 명령이 정확히 어떻게 작동 합니까 (소스 코드를 찾으려고했지만 실패했습니다)?



답변

touchutimes파일의 수정 시간 및 액세스 시간을 설정하기 위해 시스템 호출을 호출합니다 . 일부 시스템에서는 utimes파일 대신 파일을 열고 디스크립터를 통해 파일 시간을 설정합니다 (예 utimensat: Linux에서).

touch시스템 호출을 확인하여 시스템 작동 방식을 확인할 수 있습니다 . Linux에서는 strace를 사용하십시오 ( 예 🙂strace touch -d '1 hour ago' foo .

소스 코드를 찾는 위치는 운영 체제에 따라 다릅니다. GNU 버전은 coreutils 에 있고 BSD의 기본 소스 트리에 버전이 있으며 BusyBox , Minix 등 의 버전이 있습니다 .


답변

때로는 소스 코드가 필요하지 않습니다. 사용하십시오 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사용하여 파일의 타임 스탬프를 업데이트하는 기능이 있습니다. 그것이 내부적으로 작동하는 방식입니다.


답변

다음은 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)


답변