我有一个脚本,它总是在我将其重定向到文件的位置提供输出,我想做的是旋转重定向的文件,下面是我启动脚本并重定向它的位置:
.
somecode
.
su - username -c "command >> /path/to/directory/output.txt" &
.
.
code continues..
下面是我正在尝试创建的 crontab:
cd /path/to/directory/
timestamp=`date "+%Y%m%d"`
mv ./output.txt ./logs/output.txt_$timestamp
touch output.txt
chmod 757 ./output.txt
gzip ./logs/output.txt_$timestamp
find ./logs/output.txt* -type f -mtime +2 | xargs rm
或者这个也未能完成这项工作:
timestamp=`date "+%Y%m%d"`
cp ./output.txt ./logs/output.txt_$timestamp
echo "" > ./output.txt
gzip ./logs/output.txt_$timestamp
在第一个代码中,原始脚本失败并且不再工作,在第二个脚本中,它不会清理output.txt 文件。
有没有办法在保持脚本运行的同时做到这一点?笔记;我正在运行 Unix Solaris。
提前致谢。
答案1
这通常是通过添加一个来完成的叹息重新启动命令的处理程序在其他一些命令(通常logrotate
)移动文件之后。在 *nix 操作系统上,您可以在写入文件时移动文件(我相信,但需要注意的是,它必须仍然位于同一文件系统上);额外的行将附加到新位置的文件中。
答案2
您确实无法更改正在运行的进程的重定向stdout
和/或stderr
新文件(请参阅下面的注释)(这是使用重定向stdout
或stderr
作为长时间运行的进程的日志文件的原因之一坏的主意。)
当进程启动时,命令的重定向元素由启动进程的 shell 执行。如有必要,会以适当的模式(追加或覆盖)打开和创建目标文件,并且可能根据重定向模式将其截断为零字节。然后打开的文件描述符被传递给子进程。从字面上看,该打开的文件描述符是子进程拥有的指向重定向文件的唯一链接。这是文件的链接。
这是重要的一点 - 作为直接到文件的链接,打开描述符与文件的目录条目 - “文件名”相同。更改该名称甚至删除该目录条目(例如使用rm
命令)对进程中打开的文件描述符绝对没有影响。
@l0b0 的答案是正确的,需要轮换日志的进程倾向于使用SIGHUP
处理程序来执行此类轮换,但在重定向输出的情况下“轮换日志”并不是那么简单 - 新的输出文件的名称是什么?子进程不知道它的“名称”是什么stdout
和/或是stderr
什么 - 并且输出“文件”甚至可能不是文件。
日志轮换方案必须是设计的到流程中 - 日志记录应该以这样的方式集成,例如,日志条目不会在旋转日志文件的过程中丢失。
(好吧,可以是可能的更改正在运行的进程的stdout
/stderr
流 - 但这是必须的 - 再次 -设计的进入这个过程。这不是开箱即用的二进制文件,bash
如果您向它发送SIGHUP
...)
答案3
非常感谢大家的回复,找不到办法做到这一点,因此作为解决方法,我设置了 crontab 来停止原始脚本,进行轮换并在非高峰时再次启动。