为什么触摸只能一直改变,或者当不是拥有者时什么都没有

hbo*_*ert 7 permissions stat timestamps files touch

我们有一个foobar不属于我的文件,但它在我的组中:

$ ll
total 4,0K
-rw-rw-r-- 1 root hbogert 4 jan 19 12:27 foobar
Run Code Online (Sandbox Code Playgroud)

我可以触摸它,它会一直更新:

 $ stat foobar
  File: 'foobar'
  Size: 4           Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 4869333     Links: 1
Access: (0664/-rw-rw-r--)  Uid: (    0/    root)   Gid: ( 1000/ hbogert)
Access: 2017-01-19 12:27:04.499412133 +0100
Modify: 2017-01-19 12:27:04.499412133 +0100
Change: 2017-01-19 12:27:04.499412133 +0100
 Birth: -


 $ touch foobar


 $ stat foobar 
  File: 'foobar'
  Size: 4           Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 4869333     Links: 1
Access: (0664/-rw-rw-r--)  Uid: (    0/    root)   Gid: ( 1000/ hbogert)
Access: 2017-01-19 12:32:04.375412133 +0100
Modify: 2017-01-19 12:32:04.375412133 +0100
Change: 2017-01-19 12:32:04.375412133 +0100
 Birth: -
Run Code Online (Sandbox Code Playgroud)

但是,当我只想更改修改时间时,它失败了:

$ touch -m foobar
touch: setting times of 'foobar': Operation not permitted
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗?

Ste*_*itt 8

这种行为是预期的,如果不是很明显的话。至少在我的系统上,touch

utimensat(0, NULL, NULL, 0)
Run Code Online (Sandbox Code Playgroud)

在第一种情况下 ( touch file),和

utimensat(0, NULL, [UTIME_OMIT, UTIME_NOW], 0)
Run Code Online (Sandbox Code Playgroud)

在第二个(touch -m file)。第一个调用是“将访问和修改时间设置为当前时间”的简写;第二个说“单独保留访问时间并将修改时间更改为当前时间”。

POSIX

只有有效用户 ID 等于文件用户 ID,或对文件具有写访问权限,或具有适当权限的进程才可以使用futimens () 或utimensat () 以空指针作为时间参数或同时使用tv_nsec字段设置为特殊值 UTIME_NOW。只有有效用户 ID 等于文件的用户 ID 或具有适当权限的进程才能使用futimens () 或utimensat () 和非空时间参数,这些参数没有将两个tv_nsec字段都设置为 UTIME_NOW 并且没有两个tv_nsec字段都设置为 UTIME_OMIT。

times是 的第三个参数utimensat())。touch file属于第一组访问限制:对文件的任何写访问都允许将访问和修改时间更改为“现在”。touch -m file属于第二组访问限制:您需要成为root文件的所有者或文件的所有者才能将访问和修改时间更改为既不是“现在”也不是“未更改”的值。

还有其他方法可以将您不拥有但可以读取或写入的文件的访问和/或修改时间更改为“现在”:

  • 读取文件只会更新访问时间;
  • 写入文件(读取)只会更新修改时间。