44

After about an hour of Googling this, I can't believe nobody has actually asked this question before...

So I've got a script running on TTY1. How do I make that script launch some arbitrary program on TTY2?

  • I found tty, which tells you which TTY you're currently on.
  • I found writevt, which writes a single line of text onto a different TTY.
  • I found chvt, which changes which TTY is currently displayed.

I don't want to display TTY2. I just want the main script to continue executing normally, but if I manually switch to TTY2 I can interact with the second program.

MathematicalOrchid
  • 5,664
  • 7
  • 35
  • 62

5 Answers5

41
setsid sh -c 'exec command <> /dev/tty2 >&0 2>&1'

As long as nothing else is using the other TTY (/dev/tty2 in this example), this should work. This includes a getty process that may be waiting for someone to login; having more than one process reading its input from a TTY will lead to unexpected results.

setsid takes care of starting the command in a new session.

Note that command will have to take care of setting the stty settings correctly, e.g. turn on "cooked mode" and onlcr so that outputting a newline will add a carriage return, etc.

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
wurtel
  • 15,835
  • 1
  • 29
  • 35
  • 3
    That is not correct. You mix up the controlling terminal with `/dev/stdin`, `/dev/stdout`, and `/dev/stderr`. `ps` easily shows that `command` does not have a controlling terminal at all in your case. – Hauke Laging Nov 26 '14 at 16:49
  • 1
    @HaukeLaging, a session leader takes control of a terminal as soon as it opens it. The problem was that the terminal device was not open by the session leader. Should be fixed now. – Stéphane Chazelas Nov 26 '14 at 19:30
  • @StéphaneChazelas I tested with `sleep 1000` and it still doesn't work here. I used a pseudo tty, though (shouldn't make a difference, I guess). – Hauke Laging Nov 26 '14 at 19:38
  • @HaukeLaging How exactly did you do it? Did that terminal not have a controlling session already (the _As long as nothing else is using the other TTY_ part)? – Stéphane Chazelas Nov 26 '14 at 19:41
  • 1
    @StéphaneChazelas I ran `setsid sh -c 'exec sleep 1000 <>/dev/pts/4 >&0 2>&1'` in a terminal emulator window. `/dev/pts/4` is another terminal emulator window (same user, with `bash` running). – Hauke Laging Nov 26 '14 at 19:45
  • @HaukeLaging, then you're not meeting wurtel's requirement. You cannot take control of a terminal if it already has a controller. Try on `/dev/tty15` – Stéphane Chazelas Nov 26 '14 at 19:47
  • This worked for me when nohup did not. – GChuf Mar 11 '21 at 11:09
6

On the second tty there will be normally a program running, either some login program or some shell like bash. If you want interaction you either would have to replace the login program with yours, or tell a shell to run the program as if the program was started from the commandline.

A more simple solution, IMO, would be to start a tmux session after logging into the second screen and then use:

tmux send yourcommand ENTER

to start the program in the tmux session which will display after you switch to the second terminal.

Anthon
  • 78,313
  • 42
  • 165
  • 222
6

I just made a discovery:

How can I launch applications from 2 ttys on launch?

One of the comments mentions something called openvt. This command appears to do the exact thing I'm after!

http://linux.about.com/library/cmd/blcmdl1_openvt.htm

Unless anyone knows different, I think this is probably the "correct" way to do this.

(I just tried it, and it seems to work fine - even though getty is running, it picks the next unused terminal. I guess VTs don't get "opened" until you switch to one to try to log in...)

MathematicalOrchid
  • 5,664
  • 7
  • 35
  • 62
3

i start a new graphical session on the vt5 with the follow command

xinit "/usr/bin/<binary_executable>" -- :1 vt5

for example :

xinit "/usr/bin/playonlinux" -- :1 vt5

If you want to launch a graphical application on already active graphical session you can do with :

DISPLAY=:0 "/usr/bin/playonlinux"
inukaze
  • 461
  • 4
  • 17
0

start bash on different tty:

setsid agetty --autologin root  --noclear 19200 ttyS1 linux
jamlee
  • 111
  • 3