“感人”标准出炉?

“感人”标准出炉?

这可能看起来是一个奇怪的问题,但是假设我有一个脚本,其输出被写到一个文件中,如下所示:

myscript.sh >> /path/to/some/file

是否有可能“触摸”标准输出,以便可以更新输出文件的修改时间而无需实际写入任何内容?

显然,如果路径直接传递到脚本中,我可以使用命令轻松地执行此touch操作,但这里不是这种情况,而是我将标准输出重定向到文件。

那么,在使用 I/O 重定向时,是否有一种巧妙的方法来触及目标文件,或者我是否需要在内部或某种包装脚本内处理输出路径?

答案1

至少在 Linux 上,/dev/stdoutto 中有一个符号链接/proc/self/fd/1,它是文件的符号链接 - 所以touch /dev/stdout可以工作:

user@host:~$ ( echo hi; stat -c '%y' /tmp/foo >&2; for i in 0 1 2; do sleep 2; touch /dev/stdout; stat -c '%y' /tmp/foo >&2; done ) >> /tmp/foo
2017-11-03 07:02:59.595622835 -0400
2017-11-03 07:03:01.599680859 -0400
2017-11-03 07:03:03.603738883 -0400
2017-11-03 07:03:05.611797023 -0400

在Linux 上,当stdout 不是文件时,它会成功或不执行任何操作(例如,匿名管道,例如,./myscript.sh | less实际上有一个mtime,而套接字的mtime 始终为0)。如果 stdout 未打开(这是可能的,尽管很少见),那么它会生成一个诊断信息(“我的机器上没有这样的文件或目录”)。如果 stdout 是不可写文件,则相同。

它根本无法移植,但可能最坏的情况是产生诊断并且不执行任何操作(至少对于非 root 用户而言,他们不应该能够写入/dev)。

根据您的实际目标,可能有更好的方法。例如,也许您应该将文件名传递给脚本,然后touch直接使用它就很简单了。或者如果你这样做是为了表达“还活着!”也许您需要一个单独的文件(或使用进程管理程序和/或 pid 文件)。

答案2

您需要调用futimes()/futimens()系统调用。

使用perl,您可以通过以下方式调用它:

perl -e 'utime undef, undef, *STDOUT'

相关内容