2

I've got a process that spews out a lot of output, and it's going to be running for the next hour. I forgot to pipe its output through my awk script before I started running it. Now my terminal is full of things that make it hard to read.

Is there a way I can background the process, then resume it in the foreground with its output being piped through my script before going to the terminal?

1

1 Answer 1

2

On Linux, and assuming the process runs, as you, some dynamically linked non-setuid/setgid executable, and that /proc/sys/kernel/yama/ptrace_scope contains 0, you could write a reattach-stdout script like:

#! /bin/sh - ret=0 exec 3>&1 for pid do gdb -p "$pid" -batch-silent \ -ex 'call close(1)' \ -ex "call open(\"/proc/$$/fd/3\", 1)" \ -ex quit >&2 || ret=$? done exit "$ret" 

And call it as:

reattach-stdout "$pid" | awk... 

Where $pid is the pid of the process whose stdout you want to redirect to a pipe to awk (you can also pass more than one pid).

Note that it is quite intrusive, the processes will be suspended for a fraction of a second and the program might get confused to have the type of the file open on its stdout changed from a tty to a pipe under its feet.

It also assumes the process' fd 0 is not closed which in general should be a safe assumption.

Essentially, that uses a debugger to attach to the processes and make them close their own fd 1 and reopen it (in write-only mode) to the same resource as opened on fd 3¹ in the sh process running the script.


¹ you'd think opening /proc/$$/fd/1 should work and the exec 3>&1 should be unnecessary, but I find here that with the dash implementation of sh (not with bash's), at the time the process opens /proc/$$/fd/1, it points to the tty device, as if the >&2 had been done before the fork of the process that executes gdb.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.