9

Thanks! My usercase: I started a lengthy interactive 'configure' process (say under 'screen'), and then realised I need to always answer 'no' until I see a particular keyword. Seems a waste of time to do this by hand (not to say that I can easily miss the keyword..)

Thus it seems I want to pipe (a copy of) STDERR / STDOUT to a filter, and also be able to inject into the STDIN of a (console) process, AFTER it's been started, using command line? Is there a ready-made solution?

The following tools seem help. To capture output, use

strace -ewrite -p $PID

It's not that clean (shows lines like: write(#,) ), but works! But does it say handle UTF8 correctly?

To redirect the output, do something like

printf '..input..' >/dev/pts/33

But it is not clear how to find the right device..

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
John Quilder
  • 425
  • 4
  • 12

3 Answers3

5

Solved in Linux (apparently Linux-specific):

reptyr -s PID 

attaches a process to another terminal and/or exposes its input and output as pipes.

Adrian Frühwirth
  • 42,970
  • 10
  • 60
  • 71
John Quilder
  • 425
  • 4
  • 12
3

This is possible but it's not pretty. The process is as follows:

  1. use gdb to attach to the already running process
  2. run p close(<fd>) where <fd> is the file descriptor you want to change
  3. run p creat("<path to file">, <perms>) to send the output of the closed fd somewhere else

See This Link for more detailed information

SiegeX
  • 135,741
  • 24
  • 144
  • 154
  • 4
    Rather than `close()` on the fd, you may want to create the new fd first (`creat()`, `open()`, etc) then use `dup2()` to replace the fd you want to capture, and then `close()` the new fd. The reason is that `open()` etc will always give the lowest available fd, so if you close a fd and open right after, there's no guarantee you'll get back the same fd. Maybe not as important for stdin/stdout/stderr because they're fd 0,1,2, but worth mentioning for the general case. – FatalError Jan 28 '12 at 20:39
  • little program reptyr -s PID does just that – John Quilder Jan 30 '12 at 22:00
1

Why do you want to do that??

It is not possible in a portable Posix-ly way! Maybe open-ing the /proc/1234/fd/0 and /proc/1234/fd/1 and /proc/1234/fd/3 pseudo-files (for process 1234) could be an ugly possiblity! And even that might not work in some cases (e.g. for pipes).

In particular, I believe that the semantics of SIGPIPE sent to the process if nobody is reading a pipe would be broken...

And I don't believe that you would be able to keep the pseudo-tty quality of e.g. stdout .

So basically, you'll better find a different way to achieve your overall goals, which you did not explain explicitly.

If your use-case is some weird configure script, you could restart it and feed it with some script of your own (in shell, python, perl, etc...). Don't lose time to try to catch an existing configure process, just restart it appropriately.

Look also at the screen command (and how it is implemented!)

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Thanks! My usercase: I started a lengthy interactive 'configure' process (say under 'screen'), and then realised I need to answer 'no' – John Quilder Jan 29 '12 at 21:02
  • Thanks! My usercase: I started a lengthy interactive 'configure' process (say under 'screen'), and then realised I need to always answer 'no' until I see a particular keyword. Seems a waste of time to do this by hand (not to say that I can easily miss the keyword..) – John Quilder Jan 29 '12 at 21:09
  • Thanks again! My point is that it would be very handy sometimes to be able to do this, with any process; 'configure' is only an example..'screen' can do it something like that, but not quite: you can filter ( :exec !..| less ) either input or output, but not both. Seems I have to write my own script then.. – John Quilder Jan 29 '12 at 23:40
  • If you find that handy (but I don't) consider contributing to the linux kernel some new system calls to implement it. Then modify shells for that. Participate to the free software movement! – Basile Starynkevitch Jan 30 '12 at 06:01
  • Basile, my question is solved: reptyr -s PID does what i want, and seems reliable enough. – John Quilder Jan 30 '12 at 22:01