如何从已经运行的进程中捕获标准输出

发布于 2024-09-13 17:59:26 字数 310 浏览 10 评论 0原文

我有一个正在运行的 cron 作业,它将运行一段时间,我想查看它的标准输出。我不知道该进程是由 cron 启动的事实有多重要,但我想我会提到它。这是在 OSX 上,所以我无法访问诸如... /proc/[pid]/...、truss 或 strace 之类的东西。使用 IO 重定向执行的建议(例如 script > output & tail -f output)是不可接受的,因为此进程 1) 已在运行,并且 2) 无法停止/重新启动重定向。如果有可以在各种 Unices 上工作的通用解决方案,那将是理想的,但具体来说,我现在正在尝试在 Mac 上完成此任务。

I have a running cron job that will be going for a while and I'd like to view its stdout. I don't know how important the fact that the process was started by cron is, but I figure I'd mention it. This is on OSX so, I don't have access to things like... /proc/[pid]/..., or truss, or strace. Suggestions of executing with IO redirection (e.g. script > output & tail -f output) are NOT acceptable, because this process is 1) already running, and 2) can't be stopped/restarted with redirection. If there are general solutions that will work across various Unices, that'd be ideal, but specifically I'm trying to accomplish this on a Mac right now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我爱人 2024-09-20 17:59:26

OSX 的真正解决方案

将以下函数写入您的 ~/.bashrc~/.zshrc

capture() {
    sudo dtrace -p "$1" -qn '
        syscall::write*:entry
        /pid == $target && arg0 == 1/ {
            printf("%s", copyinstr(arg1, arg2));
        }
    '
}

用法:

example@localhost:~$ perl -e 'STDOUT->autoflush; while (1) { print "Hello\n"; sleep 1; }' >/dev/null &
[1] 97755
example@localhost:~$ capture 97755
Hello
Hello
Hello
Hello
...

https://github.com/mivok/squirrelpouch/wiki/dtrace

注意:

您必须在 El Capitan 或更高版本上禁用 dtrace 限制。

csrutil enable --without dtrace

True solution for OSX

Write the following function to your ~/.bashrc or ~/.zshrc.

capture() {
    sudo dtrace -p "$1" -qn '
        syscall::write*:entry
        /pid == $target && arg0 == 1/ {
            printf("%s", copyinstr(arg1, arg2));
        }
    '
}

Usage:

example@localhost:~$ perl -e 'STDOUT->autoflush; while (1) { print "Hello\n"; sleep 1; }' >/dev/null &
[1] 97755
example@localhost:~$ capture 97755
Hello
Hello
Hello
Hello
...

https://github.com/mivok/squirrelpouch/wiki/dtrace

NOTE:

You must disable dtrace restriction on El Capitan or later.

csrutil enable --without dtrace
哭泣的笑容 2024-09-20 17:59:26

免责声明:不知道 Mac 是否有这个。 Linux 上存在这种技术。 YMMV。

您可以从 /proc 获取 stdout/err (假设有适当的权限):

PID=$(pidof my_process)
tail -f /proc/$PID/fd/1

或者将缓冲区中剩余的所有内容获取到文件:

cat /proc/$PID/fd/1

PS:fd/1 是 stdout,fd/2 是 stderr。


编辑:亚历克斯·布朗> Mac 没有这个,但对于 Linux 来说这是一个有用的提示。

DISCLAIMER: No clue if Mac has this. This technique exists on Linux. YMMV.

You can grab stdout/err from /proc (assuming proper privileges):

PID=$(pidof my_process)
tail -f /proc/$PID/fd/1

Or grab everything remaining in the buffer to a file:

cat /proc/$PID/fd/1

PS: fd/1 is stdout, fd/2 is stderr.


EDIT: Alex brown> Mac does not have this, but it's a useful tip for Linux.

抱猫软卧 2024-09-20 17:59:26

使用dtruss -p,甚至rwsnoop -p

use dtruss -p <PID>, or even rwsnoop -p <PID>.

眼中杀气 2024-09-20 17:59:26

neercs 能够“抓取”在其外部启动的程序。也许它对你有用。
顺便说一句,你没有 truss 或 strace,但你有 dtrace。

neercs has the ability to "grab" programs that were started outside it. Perhaps it will work for you.
BTW, you don't have truss or strace, but you do have dtrace.

赏烟花じ飞满天 2024-09-20 17:59:26

我认为你从 cron 开始的事实可以拯救你。在 Linux 下,任何 cron 作业的标准输出都会被邮寄到拥有该作业的用户的 unix 邮件帐户。但不确定 OSX。不幸的是,您必须等待作业完成才能发送邮件并且可以查看输出。

I think the fact you started with cron could save you. Under linux any standard output of a cron job is mailed to the unix mail account of the user who owns the job. Not sure about OSX though. Unfortunately you will have to wait for the the job to finish before the mail is sent and you can view the output.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文