Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I capture the stdout from a process that is ALREADY running

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.

like image 538
theraccoonbear Avatar asked Aug 06 '10 15:08

theraccoonbear


People also ask

How do I find the stdout of a process?

Since you have the PID (returned from posix_spawn ) and you are running Linux, you will find the stdout of the process at /proc/<pid>/fd/1 . Just open (or fopen ) the file for reading. The standard way is to use fork though. Use pipe and dup2 to get a file descriptor for reading the child's output, as in this question.

How do I redirect the output of an already running process?

The way we can redirect the output is by closing the current file descriptor and then reopening it, pointing to the new output. We'll do this using the open and dup2 functions. There are two default outputs in Unix systems, stdout and stderr. stdout is associated with file descriptor 1 and stderr to 2.

What command would you use to duplicate stdout from a program to both stdout and a file?

The tee command, used with a pipe, reads standard input, then writes the output of a program to standard output and simultaneously copies it into the specified file or files. Use the tee command to view your output immediately and at the same time, store it for future use.

How do I send output to stdout?

Redirecting stderr to stdout When saving the program's output to a file, it is quite common to redirect stderr to stdout so that you can have everything in a single file. > file redirect the stdout to file , and 2>&1 redirect the stderr to the current location of stdout . The order of redirection is important.


1 Answers

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 
like image 152
mpyw Avatar answered Oct 08 '22 03:10

mpyw