`touch`命令的合法用途是什么?


83

touch命令的目的是什么?我知道我可以使用它创建空文件,但是使用也是这样echo -n

否则,为什么有人需要更改文件的时间戳?除非造成对文件使用年限的错误印象,否则我看不到任何其他用途,并且这不是合法用途(从我的角度来看)。


15
代替echo -n > filename,您可以运行以下命令:>filename
AMADANON Inc. 2014年

77
什么是不合法的用途?
bmargulies

10
Unless to create the false impression about the age of a file。不必要的错误印象。如果更改修改时间怎么办?在脚本中可能很有用。该脚本在很大程度上取决于touch命令,拥有这样的脚本非常方便和简单。
VL-80

7
考虑一下他们tar(或其他解归档器)提取归档文件时的操作。通常,他们将文件的修改时间设置为来自存档的时间,而不是提取存档的时间,这是理想的功能。由于用户模式程序创建错误的时间戳是合法的,因此没有太多的理由说明为什么touch(或某些其他命令行程序)不允许基于命令行参数来使用它。学习C语言并不能使您比编写sh脚本的人更合法;-)
史蒂夫·杰索普

5
在UNIX中,没有描述age文件的时间戳。这将是一个creation时间戳,而UNIX中没有这样的时间戳。
凯文·费根

Answers:


98

touch它的优点之一是它可以指定任意时间戳,而echo -n始终会生成当前时间。

合法使用的一个示例是更新源代码文件的时间戳,以便类似程序make将源文件视为比其编译对象新的源,然后重新构建它。

其他用途是创建仅基于文件存在而起作用的文件,例如/etc/nologin,如果存在则禁止登录。我还认为这touch myfile是一个比echo -n >> myfile,更简单,构造更简单的构造。


18
另一个常见用法:将文件触摸到特定日期,然后“查找/-较新的/ the / file”以查找所有在此之后更改/创建的文件
Olivier Dulac 2014年

@casey查看文档时,echo -n我看到它说“不输出尾随换行符”。因此,我看不到如何创建一个空文件。你能澄清一下吗?
极客

3
@Geek echo -n将输出一个空字符串,并且本身不执行任何操作。通过重定向其输出>>会导致将空输出附加到文件中。如果该文件不存在,重定向将导致该文件被创建。
casey 2014年

6
那是行不通的:打开现有文件进行输出,但不写入该文件,不会更改mtime(无论如何在我的系统上)。即使这样做,您也不需要也不应该将其echo -n用于不执行任何操作的命令。echo -n可能会在某些shell下输出字符串“ -n”。如果您确实需要一个不执行任何操作的命令,:或者true是一个更好的选择,但是>> myfile如果该命令不存在,那么它本身也是一种完全有效的创建文件的方法。当然,所有这些都支持您应该只使用“触摸”的答案。
2014年

40

底层的系统调用(utime)对于各种实用程序都很重要,例如tar能够设置新复制(未压缩)文件的时间戳。还可以选择某些备份实用程序来重置其复制文件的最后访问时间。

一种合理的用法touch是创建带有特定时间戳记的文件。这样的“参考”文件可以被诸如之类的命令使用find。例如,要查找比2013年11月1日(即2013/11/01)更新最近的所有文件”

touch -amt 201311010000 myref
find . -type f -newer myref -exec ls -ld {} +

如何计算201311010000 意味着2013年11月1日?有实用程序可以告诉我这一点吗?换句话说,我如何确定要触摸的输入?
极客2014年

4
@Geek通过查看数字并注意第一部分20131101可以细分为2013-11-01或2013年11月1日。然后,您可以假定该0000部分指示一天中的特定时间,在这种情况下为00小时00分钟。或者,您可以仅查看的手册页touch,该手册确切地告诉您格式是什么(请参阅参考资料-t)。
JAB

@Geek手册页是您的朋友:-)
JRFerguson 2014年

39

touch命令的主要目的是操纵文件的时间戳,并用于创建文件。

例子

1.创建文件

$ ls -l
total 0

$ touch file{1..3}

$ ls -l
total 0
-rw-rw-r--. 1 saml saml 0 Jan 12 13:33 file1
-rw-rw-r--. 1 saml saml 0 Jan 12 13:33 file2
-rw-rw-r--. 1 saml saml 0 Jan 12 13:33 file3

注意:total 0输出ls -l是正确的。的此实现ls显示了列出文件时文件正在使用的块数。您可以通过将-s开关添加到来确保这一事实ls。这将列出每个文件正在使用的块。在这里,我向file1和file2添加了2个字符。

$ ls -ls
total 8
4 -rw-rw-r--. 1 saml saml 3 Jan 13 12:07 file1
4 -rw-rw-r--. 1 saml saml 3 Jan 13 12:09 file2
0 -rw-rw-r--. 1 saml saml 0 Jan 13 12:05 file3

2.文件的时间/日期信息-stat命令

$ stat file1
  File: ‘file1’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd02h/64770d    Inode: 11403667    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/    saml)   Gid: ( 1000/    saml)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2014-01-12 13:33:38.279456149 -0500
Modify: 2014-01-12 13:33:38.279456149 -0500
Change: 2014-01-12 13:33:38.279456149 -0500
 Birth: -

我们可以touch用来操纵给定文件上的各种时间戳。

3.摘录自触摸手册页

   -a     change only the access time
   -m     change only the modification time
   -t STAMP
          use [[CC]YY]MMDDhhmm[.ss] instead of current time

4.操纵访问时间

$ touch -a -t200001010000 file1

$ stat file1
  File: ‘file1’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd02h/64770d    Inode: 11403667    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/    saml)   Gid: ( 1000/    saml)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2000-01-01 00:00:00.000000000 -0500
Modify: 2014-01-12 13:33:38.279456149 -0500
Change: 2014-01-12 13:38:52.023434696 -0500
 Birth: -

5.操纵修改时间

$ touch -m -t200001010000 file1

$ stat file1
  File: ‘file1’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd02h/64770d    Inode: 11403667    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/    saml)   Gid: ( 1000/    saml)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2000-01-01 00:00:00.000000000 -0500
Modify: 2000-01-01 00:00:00.000000000 -0500
Change: 2014-01-12 13:39:31.060432026 -0500
 Birth: -

您可能想知道更改时间(ctime)。不能使用来操纵touch。这将跟踪在文件上触摸任何元数据的时间。有关标题的更多详细信息,请参见此U&L问答:在不触发“更改”时间戳的情况下可以对文件做什么?


@sim:我的问题暗示我知道触摸是为了更改时间戳。我只是想知道为什么诚实的用户会想要那个。如果不是您的答案的ctime部分,我会给您-1。
Quora Feans 2014年

16
@QuoraFea-我的回答是为了您的利益以及将来遇到的用户。请不要以为答案纯粹是为了您的利益,如果您以任何方式冒犯了您,我很抱歉,这不是我的意图,我只是在试图解释时间如何运作的基础。
slm

@sim:我没有冒犯,只是以为答案没有朝着正确的方向前进。无论如何,感谢您的回答。
Quora Feans 2014年

@QuoraFea-非常欢迎您,并感谢您的提问。非常感谢!
slm

1
@Geek-尝试命令。这是从ls -l文件大小为0的目录中正确输出的,并且没有其他文件。只要您提供其中一个文件大小,总和就会显示出文件正在使用的块数。如果不确定,请查看我的更新,我添加了一个示例。
slm

20

除了您获得的其他两个非常好的答案之外,用您的话来说,另一个用途是

产生关于文件使用期限的错误印象

例如用于备份方案。您可能不希望使用较新的备份来更新备份,因为它们是相同的,或者与将更新备份到较慢的线路(例如到远程主机)的开销相比,这些更改无关紧要。为此,您可以使用简单的选项将备份文件标记为较新的时间戳,而不是伪造,而是声明该文件的有效时间戳现在与以前不同。

关于文件使用年限的印象现在确实是错误的,但是其含义是真实和合法的。


20

最常见的用途之一touch是-或至少曾经是-触发代码重建。

常用的构建工具make及其衍生工具会尝试通过不重新编译/重建文件来节省工作,除非用于创建它们的文件之一已更改-例如,如果.o文件比.c更新,源代码,通常可以安全地假设C源代码自从被编译为生成该目标文件以来就没有被更改过。

但是有时候您想强制重建某些内容。您可以对其源文件之一进行不必要的修改,但是这样做有可能意外损坏某些内容。取而代之的是,您可以简单地touch将文件设置为新文件,而无需担心更改其内容的风险-这足以使您确信make是时候重建依赖该文件的所有内容了。

还有其他用途,但从历史上看,这是最大的用途。


虽然它是更改文件以进行重建的好主意,但我反对这样做。某些源代码修订系统可能会对更改的文件感到困惑。因此touch就像手动更改一样糟糕。要进行重建,建议删除.o相关源的输出文件。
哈珀2014年

1
手动更改和删除.o文件都需要更多时间和打字,而手动更改更容易出错。我们只是在谈论修改工作副本上的时间戳-如果事后进行编辑,则文件将正确反映更改时间戳。并非所有版本控制系统都会被时间戳弄糊涂。
大卫

1
正如大卫所说。不久前,这确实是标准的Unix惯例,对于在IDE之外工作的开发人员来说,仍然是标准惯例。
keshlam 2014年

12

我与至少一个Web框架(不记得哪个)合作,在开发模式下它监视源代码文件的更改并在发生这种情况时重新加载应用程序。

当然,有时您希望它在更改了它不关注的内容之后重新加载,在这种情况下,touch通过其主要配置文件可以解决问题。

因此,在通常情况下,只要您要启动由文件更改触发的过程,而无需实际更改文件。


4
实际上,mod_wsgi和apache就是这种情况。您只需触摸wsgi文件即可重新加载django网络应用程序。
sapi 2014年

11

合法使用触摸:

  • 将图像文件(GIF / JPG / etc)的时间戳更新为拍摄时间。并非所有渲染器都读取或注意EXIF信息。
  • 批量更新一组文件时,请保持c / m-time,其中时间戳对于文件捆绑包很重要。
  • 如果您需要在失败后进行其他导入,请设置批处理(即CSV)文件的时间,并且导入程序取决于时间戳(将讨论留给另一个主题:-))
  • 存档目的,即在基于年份的文件夹中进行备份,然后将这些文件夹上的时间设置为YYYY 1月1日,以便于排序

7

一种用途是更正未正确设置的文件的时间戳。

例如,大多数复制文件的方式(以及某些可能移动文件的方式)都会导致新文件具有当前时间的时间戳,而不是原始文件的时间戳。

通常,这不是所期望的。触摸可以“修复”该问题。

另一个用途是通过将文件时间戳恢复为“ edit ... undo-edit”操作之前的时间戳来反映撤消的文件修改。


2
确实。我发现alias cp='cp --preserve=timestamps'在PC领域更适合我
度过

5

一个重要的区别与things类似echo(或更好的> file为其他人所说)是触摸不会粉碎的内容。> file将清空文件。touch将不会。与其想办法避免内容损坏,不如使用触摸!无论如何,它将在内核中完成较少的工作,因为它将仅使用文件的属性,而不会浪费时间实际为打开做准备,然后执行关闭。

即使文件当前处于强制性或咨询性锁定或互斥打开状态,触摸也可能会更改时间戳。嗯,从来没有测试过或者没有读过它...


2
>>将追加而不是覆盖
Michael Mrozek

我考虑过要提到这一点,但是它正在更多地进入副作用领域。您还必须提到一个事实,如果该文件恰巧已经被独占打开,则将引发错误等,等等。通过使用>也可以解决此问题。我想我的第二要点-除了第一要点之外,仅触摸文件的统计信息就快一点-是写一个直截了当地的代码而不是乱花钱的好主意。

4

这是一个-我使用一个名为SageTV的软件程序来录制电视节目-这些节目通常以MPEG-2录制,这不是一个非常高效的编解码器,它也不适合iPad / iPhone。因此,我将文件转换为.mp4文件。但是,在播放文件时,SageTV希望文件的时间戳记是在电视节目开始时开始的-如果没有,则它会弄乱节目的时间轴,因此不容易FF或REW。因此,我使用touch将.mp4文件的时间戳重置为与原始文件相同的时间戳。
那是合法的吗?


2

通常,您的进程可能会从userid更改,例如从root->其他更改。Touch可以让您有机会在一个根目录下创建文件,该目录在应用程序开始以其他用户身份登录之前只有root可以触摸。


这不是一个使用手感,到是无法实现的“回声” -看到作者的最初的问题
多明戈·伊格纳西奥·加尔多斯

回声涉及打开流等。通过直接使用inode可以对触摸进行超优化。性能FTW!
user56560 '17

2

在工作中,我们拥有可追溯15年以上的数字地图档案。这些旧地图以多种格式保存,例如大多数程序不了解的PostScript,EMF,PRN,hpgl2,pdf等。或者,您需要一打不同的程序才能看到它们。

为了便于轻松搜索和浏览所有这些不同格式,我们创建了地图的jpeg版本,然后使用touch使jpeg文件与原始源文件时间戳匹配-通常是在原始文件创建后的几年。

现在,我们可以使用单个程序(例如Picasa)查看整个库并轻松定位某些日期范围。如果不加触摸,我们将不得不为每个图像添加日期元数据(可能需要手动添加),然后在查找特定日期范围时在这些字符串上进行搜索。


1

我尚未为此目的使用它,但是我有一个脚本可以从目录中读取文件及其日期,并读取它们以在网页上使用。如果我必须编辑一个,它将更改其日期。我已经考虑过touch让他们重置订单。


1

一些初始化脚本会将配置文件的时间戳与自己的pid文件进行比较。结果决定是否重新加载正在运行的服务。

如果您不想更改配置但想强制重新加载,请在此处触摸帮助。


0

我有一个cron作业,它从数据库中获取在作业的最后一次运行与当前运行之间发生的更改。它生成更改的XML文件,然后将其处理到另一个数据库中。它从XML输出文件上的时间戳获取最后的运行时间。*

如果在处理XML文件时出现任何问题,我可能要从原始日期开始重复运行,而不是从新XML文件的时间戳所指的日期开始重复运行。

实现此目的最简单的方法,而不是编辑称为etc的脚本,是触摸XML文件并将时间戳记设为我需要的日期。

同样,如果我重新开始(没有以前的XML输出文件),我可以简单地使用touch模拟它的存在。

[*]在有人指出之前-我意识到工作开始的时间,并且XML文件的写入留下了可能发生数据库更改的几分钟的时间间隔。该作业在数据库更改极不可能的时候运行。那是我的借口,我坚持:-)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.