意外删除运行进程`python Something.py 2>&1 | 的日志文件 三通.log`。有没有办法仍然将输出保存在 tmux 窗格上?

bax*_*ear 39 linux zsh python logging tmux

不小心删除了正在运行的进程的日志文件python something.py 2>&1 | tee .log。该脚本在 zsh 上的 tmux 窗格中运行。该进程仍在运行,但不记录日志。输出本身溢出 tmux-scrollback-buffer。我可以以某种方式(管理员/sudo 权限)再次启动日志记录过程而不重新启动该过程吗?

通常,我的尝试不会出现问题,并且代码与安全或任何类型的生产无关,而只是复杂的数学计算。所以,这样的尝试始终是足够的。

在我目前的情况下,如果我可以在不重新启动进程的情况下再次开始日志记录,那就太好了。

use*_*686 68

只要tee进程持有打开的文件描述符,文件就会继续存在,并且所有内容仍然记录在那里。您可以通过 /proc 复制它们来恢复其当前内容:

\n
    \n
  1. 查找“tee”进程的 PID。

    \n
  2. \n
  3. 使用lsfd -p <PID>lsof -p <PID>ls -l /proc/<PID>/fd查找与打开的文件对应的文件描述符号。(它甚至会在文件名旁边标记为“(已删除)”。)

    \n

    对于诸如“tee”之类的简单程序,打开的第一个文件几乎总是 FD #3,因此本文中的所有示例也将使用3

    \n
  4. \n
  5. 通过以下方式将文件的内容复制到新文件/proc

    \n
    cp /proc/<TEE_PID>/fd/3 old.log\n
    Run Code Online (Sandbox Code Playgroud)\n

    (/proc/PID/fd 中的符号链接是特殊的 \xe2\x80\x93,打开它们仍然可以解析为正确的文件,即使符号链接看起来已损坏,或者即使它指向的东西甚至不是真正的文件。)

    \n
  6. \n
\n

也可以让 'tee' 开始写入新文件:

\n
    \n
  1. gdb调试器附加到进程:

    \n
    $ sudo gdb -p <TEE_PID>\n
    Run Code Online (Sandbox Code Playgroud)\n

    这将暂停“tee”。如果 Python 程序产生足够的日志输出来填充管道缓冲区,它也可能会暂停(否则它不会注意到)。

    \n
  2. \n
  3. 如果您还没有 \xe2\x80\x93 使用 /proc 技巧来恢复旧的日志文件(通过另一个 shell,而不是从 gdb 内):

    \n
    $ cp /proc/<TEE_PID>/fd/3 old.log\n
    Run Code Online (Sandbox Code Playgroud)\n

    通过在附加 gdb之后(即当“tee”挂起时)执行此操作,您可以避免在“cp”和 open() 之间的间隙丢失消息。

    \n
  4. \n
  5. 现在使用 gdb 关闭 'tee' 并重新打开文件:

    \n
    (gdb) p (int) close(3)\n$1 = 0\n\n(gdb) p (int) open("new.log", 01|0100|02000, 0666)\n$2 = 3\n\n(gdb) q\nDetach? y\n
    Run Code Online (Sandbox Code Playgroud)\n

    (这些值01|0100|02000等于fcntl.hO_WRONLY|O_CREAT|O_APPEND中的值,这使得 open() 调用的行为类似于shell 运算符。)>>

    \n

    对于诸如“tee”之类的简单情况,open() 极不可能为您提供除原始#3 之外的任何其他文件描述符,因为这是最低的可用 FD。但在某些情况下,程序更复杂(如果存在编号间隙),可能需要调用dup2($2, 3)close($2)手动将新打开的文件移动到所需的 FD。

    \n
  6. \n
  7. 旧文件现在将完全消失(因为它已被删除并且最后一个文件句柄已关闭),但“tee”将写入新文件而不会注意到任何事情。

    \n
  8. \n
\n

注意:除了打开新文件之外,还可以使用linkat()在不中断任何内容的情况下使原始日志文件存在,但我还没有对此进行测试。(编辑:不幸的是,根据 linkat() 文档,这对于完全取消链接的文件不起作用。)

\n

  • 这太棒了。 (12认同)
  • `tail -f -n +1 /proc/&lt;TEE_PID&gt;/fd/3 returned.log` 会起作用吗? (2认同)