0

There seem to be plenty of similar questions, for example:

https://stackoverflow.com/questions/5374255/how-to-write-data-to-existing-processs-stdin-from-external-process

However the answer given is to prepare the program beforehand by making its stdin a pipe.

There's also:

https://serverfault.com/questions/178457/can-i-send-some-text-to-the-stdin-of-an-active-process-running-in-a-screen-sessi

Which is answered by commanding a terminal multiplexer under which the program in question is running. That means it also needs prior preparation.

This question is about how to do this without having done any preparation beforehand.

At first I thought it might be as simple as:

echo foo > /proc/$p/fd/0

but that just writes to the terminal. So then I tried:

echo foo > /proc/$terminal_emulator/fd/$ptmx_fd

but that also fails because it just opens up a new terminal device slave for echo.

I already have an answer using gdb (sigh) which I'll be posting below, but I wonder if anyone knows of a simpler and better alternative.

JoL
  • 4,735
  • 1
    https://unix.stackexchange.com/questions/306806/send-commands-to-another-terminal – Mark Plotnick Aug 06 '19 at 23:00
  • 1
    @MarkPlotnick That answer works. I'm not sure what to suggest here. Should this be marked as a duplicate of that, or would you make an answer that references and/or quotes that answer? – JoL Aug 07 '19 at 01:00
  • TIOCSTI only works as root or on the controlling tty. And writing stuff into the master side of the tty only works when it's a pseudo-tty, and you can attach to the process holding the master fd -- in the case of a ssh session, that would be a process running as root. Anyways, for yet another TIOCSTI sample, you can also look here. –  Aug 07 '19 at 01:15
  • If you're satisfied that one of the other questions/answers qualifies as a duplicate, you can click on close just below your question, then Duplicate of, then paste the URL of the duplicate question. – Mark Plotnick Aug 07 '19 at 18:29
  • @MarkPlotnick Thanks for the info. – JoL Aug 07 '19 at 20:21
  • @JoL You can accept the duplicate which is easier than 5 reviewers agreeing: Yes this is the perfect duplicate... – Fabby Aug 09 '19 at 21:27
  • 1
    @Fabby I hadn't noticed I could do that. Thanks for the heads-up. – JoL Aug 09 '19 at 23:29
  • We live and we learn... ;-) Thank you! 0:-) – Fabby Aug 10 '19 at 14:38

2 Answers2

0
#!/usr/bin/zsh

pid="$1"
stdin_data="$2"

for p in $(pstree -sp "$pid" | grep -Po '(?<=\()\d+(?=\))' | tac); do
  [[ -r "/proc/$p/fd" ]] || continue
  for f in /proc/$p/fd/*; do
    if [[ "$(readlink "$f")" = /dev/ptmx ]]; then
      fd="$(basename "$f")"
      break 2
    fi
  done
done

sudo gdb -p "$p" --batch -x =(printf '%s' '            
  p (int)write($fd, "$stdin_data", (int)strlen("$stdin_data"))
')

I don't like that the script argument can be a C injection.

JoL
  • 4,735
0

Apparently you can't, writing to a process' stdin file doesn't make the process read what you appended. See this answer for a full explanation: https://serverfault.com/a/962956