15

Suppose you have a terminal emulator (T1) open with a PID of 6350.

From another terminal, type this command (C1):

echo "ls\n" > /proc/6350/fd/0

This writes ls and the new line in T1 but does not execute it. Why?

I also tried using cat|bash with echo "ls\n" > /proc/catid/fd/0 but it is still not executed.

How can I echo the command into another terminal and have the command executed?

possible answer :

$ mkfifo toto;
$ bash < toto;
$ echo "ls" > toto;

In this case you cannot write anymore directly in the terminal (everything is displayed the same way the command (C1) displayed thing in this terminal.

5
  • stackoverflow.com/questions/3846033/…
    – rush
    May 22, 2012 at 13:22
  • I read that, but it is not very helpful.
    – rvlander
    May 22, 2012 at 14:12
  • 1
    It may not be "useful" as in giving you a way to do it, but it answers your question: you can't. You could tell us the end goal you're trying to accomplish and see if there's another way.
    – Kevin
    May 22, 2012 at 14:58
  • Ok you can't but then why the text is displayed in the other terminal ?
    – rvlander
    May 22, 2012 at 15:07
  • because you send the text to terminal interface, not to the shell.
    – rush
    May 22, 2012 at 18:51

2 Answers 2

15

There is a command line utility called ttyecho that can send a command to another terminal (tty/pts) and have the command executed.

sudo ttyecho -n /dev/pts/5 ls

See: Utility to Send Commands or Data to Other Terminals (tty/pts)

Also see: ttyecho source code on github.

Another interesting tty command is selector, a real-time interactive pattern matcher in console that updates the tty input buffer.

# selector examples
selector -v -x @ <(find . -maxdepth 2 -type d | awk '{print $0"@cd "$0}')
selector -v -x @ <(grep -E -o 'http[^ ]+' fileWithURLS)

See: selector - DYNAMIC SEARCH IN CONSOLE

1
  • 1
    Sadly, the link to ttyecho source code on github seems to be broken. However, it seems to be available at github.com/osospeed/ttyecho instead, now.
    – Wilson F
    Jun 26, 2017 at 19:49
9

When you issue a write to /dev/pts/X (/proc/6350/fd/0, 1 and 2 is just a symlink to that), what happens is exactly the same thing that happens when process 6350 (or one of its children, suitably forked) outputs something: it writes to the terminal.

If you try to read from that device (cat < /dev/pts/X), funky things will happen. You should see the things you type in the original shell show up. (Quite possibly only after the first new line you typed - I'm guessing the terminal program (xterm or whatever you're using) does some line buffering, and the 6350 shell that was blocked on read gets that piece; then either shell might, or might not, win the subsequent reads, but I might very well be completely wrong on this.)

The thing is: when you read from or write to that device, you're not talking to the other shell that is using it. You're talking to the terminal emulator (xterm for example). Only the terminal emulator can inject data into that channel (what the shell reads), and all that the shell writes goes to the terminal. Attaching a second shell doesn't change that.

If you want to inject commands into that 6530 process, it will have to do that via the terminal (whether that's an X11 app or something else).

Recommended reading: What is the exact difference between a 'terminal', a 'shell', a 'tty' and a 'console'?

3
  • 1
    Interestingly, reading from the pts (cat /dev/pts/x, you don't need <) I get the letters strictly alternating between the terminals.
    – Kevin
    May 22, 2012 at 18:50
  • Not using the redirection probably doesn't change much. I get non-predictable output either way.
    – Mat
    May 22, 2012 at 18:52
  • Interesting, thanks for the link. So /proc/6350/fd/0 is a simlink to the stdin parent of process 6350 which is a terminal. I guess it is the same for windowed applications ?
    – rvlander
    May 23, 2012 at 7:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .