从已运行的脚本重定向 stderr

从已运行的脚本重定向 stderr

我已经运行脚本好几天了。我将 stdout 重定向到$HOME/mylog,但没有重定向 stderr ,因为我认为上面不会有任何内容。突然间,stderr 上开始出现数千行,所以我暂停了这项工作。有没有办法$HOME/myerr从现在开始将 stderr 重定向到,而无需重新启动脚本?

我对盒子有 sudo 访问权限,它是 OS X。

也许使用 dtools 捕获的东西?

我不能丢失脚本迄今为止所做的工作并从头开始重新启动它。有没有办法在磁盘上“转储内存中的对象”,冻结程序,编辑变量(例如文件描述符)和恢复与新的背景?

答案1

我觉得如果把相关解释器的进程附加到gdb上是可以的。我用这个 perl 单行代码尝试过

 perl -e 'do { print "x\n"; sleep(1) } while(1)'

它可以工作,但不幸的是不能使用类似的 bash 脚本。


首先,您必须找出要捕获其输出的进程的 PID。然后在另一个终端启动gdb并执行以下 gdb 命令

attach PID
call close(2)
call open("/abs/olu/te/path/filename", 65, 384)
detach PID

之后写入的整个数据stderr将重定向到/abs/olu/te/path/filename,因为

  • attach PID将进程附加到 gdb 并停止它
  • call close(2)关闭stderr进程的文件描述符(stdout文件描述符为1)
  • call open(...)打开一个新文件,并为新创建的文件描述符取最小的未使用整数,并且
  • detach PID继续该过程

至少在我的机器上是这样。前两行与 POSIX 兼容,但第三行不兼容。

第三行中的第二个和第三个参数open记录在 中man 2 open。在我的例子中,65 意味着open应该创建文件并以只写方式打开文件,即O_WRONLY | O_CREAT(在 中定义fcntl.h)。第三个参数告诉 open 创建具有用户 ie 读写权限的文件S_IWUSR | S_IRUSR(在 中定义sys/stat.h)。所以也许你必须自己找出适合你机器的值。

答案2

这是一个粗略的答案,我希望其他人做得更好,但如果没有其他想法,请附加 gdb 并强制进程进行一些系统调用:

(gdb) attach 12345 # target PID
(gdb) p close(2)
(gdb) p open("errfile", O_WRONLY)
(gdb) c

相关内容