Is there a way to connect a shell to a pseudo tty?
The question presupposes you have a single server process but in fact you would need two.
One process is your 'backgrounded' application using the slave end of the pty.
The other process would be a helper which manages the master end of the pty.
The master end must remain opened at all times. The pty pair is removed when the masters file descriptor is closed.
The backgrounded applicaiton on the slave side, reads and writes to its end.
The master side decides what to do with those reads and writes.
To connect from another terminal you need to tell the master end where to send the read and writes.
You could give it the name of the pty terminal you are using somehow. The process managing the master end could then forward the reads and writes as appropriate.
This alone is insufficient for some applications. In particular if the terminal's size is changed the application should recieve a SIGWINCH
. The master will need to pass this to the slave somehow. The terminal capabilities could also differ and require translation.
To handle those your client side needs a third process which talks to the process running the master end of the pty. This is how screen
and tmux
work.
So there is no standard program that does what you want because there is no standard way to handle this. Programs like screen do this their own way but can be used as is in most cases.
In an answer to the linked question the OP (of that question) uses a terminal in raw mode which probably means those complications do not apply.
For example if you just want to forward stdout from the master a pty name to duplicate the output to would be sufficient.
The screen
program on the other hand creates a socket for each virtual screen (running on the master side of the pty). The same screen
executable running (in a different mode) as a client process connects to that socket to talk to the application.
Given that screen and tmux are designed explicitly to do this it is not clear what advantage you would gain from doing this yourself.
It could be an interesting learning exercise however.
The new question describes your use case better.
You could not create new user interfaces on demand with screen.
It does handle the foreground and background use case very nicely so long as you remember to run the process under screen from the outset, where screens attach and detach command would replace direct use of bg
and fg
.
How to determine which pair of pseudo tty ports are connected to each other in bash
Updated Answer
It looks like you'll have to use a file if socat
must be backgrounded.
( socat ... 2>&1 | grep -Eo "/dev/pts/\d+" > /tmp/a ) &
portA=$(head -n 1 /tmp/a)
portB=$(tail -n 1 /tmp/a)
Original Answer
@jeremysprofile 's answer is probably more sensible but, just for fun, you could do either of these also:
socat ... | grep -Eo "/dev/pts/\d+" | { read portA; read portB; }
Or, using bash's "process substitution", you could do:
{ read portA; read portB; } < <(socat ... | grep -Eo "/dev/pts/\d+")
Then you would do this after either of them:
./test_pty_app $portA &
./test_pty_app $portB &
Confused about Docker -t option to Allocate a pseudo-TTY
The -t
option goes to how Unix/Linux handles terminal access. In the past, a terminal was a hardline connection, later a modem based connection. These had physical device drivers (they were real pieces of equipment). Once generalized networks came into use, a pseudo-terminal driver was developed. This is because it creates a separation between understanding what terminal capabilities can be used without the need to write it into your program directly (read man pages on stty
, curses
).
So, with that as background, run a container with no options and by default you have a stdout stream (so docker run | <cmd>
works); run with -i
, and you get stdin stream added (so <cmd> | docker run -i
works); use -t
, usually in the combination -it
and you have a terminal driver added, which if you are interacting with the process is likely what you want. It basically makes the container start look like a terminal connection session.
Pseudo-terminal will not be allocated because stdin is not a terminal
Try ssh -t -t
(or ssh -tt
for short) to force pseudo-tty allocation even if stdin isn't a terminal.
See also: Terminating SSH session executed by bash script
From ssh manpage:
-T Disable pseudo-tty allocation.
-t Force pseudo-tty allocation. This can be used to execute arbitrary
screen-based programs on a remote machine, which can be very useful,
e.g. when implementing menu services. Multiple -t options force tty
allocation, even if ssh has no local tty.
Pretend to be a tty in bash for any command
There are a number of options, as outlined by several other Stack Overflow answers (see Caarlos's comment). I'll summarize them here though:
Use
script
+printf
, requires no extra dependencies:0<&- script -qefc "ls --color=auto" /dev/null | cat
Or make a bash function
faketty
to encapsulate it:faketty () {
script -qefc "$(printf "%q " "$@")" /dev/null
}
faketty ls --color=auto | catOr in the fish shell:
function faketty
script -qefc "(printf "%q " "$argv")" /dev/null
end
faketty ls --color=auto | cat(credit goes to this answer)
http://linux.die.net/man/1/script
Use the
unbuffer
command (as part of theexpect
suite of commands), unfortunately this requires an extra package install, but it's the easiest solution:sudo apt-get install expect-dev # or brew install expect
unbuffer -p ls --color=auto | catOr if you use the fish shell:
function faketty
unbuffer -p $argv
end
faketty ls --color=auto | cathttp://linux.die.net/man/1/unbuffer
This is a great article on how TTYs work and what Pseudo-TTYs (PTYs) are, it's worth taking a look at if you want to understand how the linux shell works with file descriptors to pass around input, output, and signals. http://www.linusakesson.net/programming/tty/index.php
how to do if else in ssh pseudo-tty allocation to remote server
You will have to quote the commands that is to be sent to the server like so:
ssh -t -t user@remote-host "
if [ -d '/test/dir_test' ]; then
sudo chown -R user:admin /test/dir_test/
sudo rm -rf /test/dir_test/*
else
sudo mkdir /test/dir_test/
fi"
Be aware that sudo
needs a password unless otherwise specified in its configuration.
What is Pseudo TTY-Allocation? (SSH and Github)
As explained in "gitolite: PTY allocation request failed on channel 0", it is important to do ssh test connection with -T
, because some server could abort the transaction entirely if a text-terminal (tty) is requested.
-T
avoids requesting said terminal, since GitHub has no intention of giving you an interactive secure shell, where you could type command.
GitHub only wants to reply to your ssh request, in order to ascertain that the ssh command does work (you have the right public/private keys, and the public one has been registered to your GitHub account)
PuTTy would be an example of a terminal emulator, serial console and network file transfer application. It supports several network protocols, including SCP, SSH, Telnet and rlogin.
The name "PuTTY
" has no definitive meaning, though "tty" is the name for a terminal in the Unix tradition, usually held to be short for Teletype.
Other use-cases for -T
(beside testing)
- Transferring binary files
- Execute commands on a remote server
- SSH tunneling:
ssh -fnT -L port:server:port user@server
(-f for background: you don't want to execute command, don't need a TTY and just want to establish a tunnel)
Related Topics
How to Use Code Completion into Eclipse with Opencv
Ftdi D2Xx Conflict with Ftdi_Sio on Linux - How to Remove Ftdi_Sio Automatically
Cuda Compiler Not Working with Gcc 4.5 +
Error: Can't Open Display: (Null) When Using Xclip to Copy Ssh Public Key
How to Delete First Two Lines and Last Four Lines from a Text File with Bash
Using Iconv to Convert from Utf-16Le to Utf-8
What Is Start-Stop-Daemon in Linux Scripting
Buffered Asynchronous File I/O on Linux
Qimage to Cv::Mat Convertion Strange Behaviour
Tiny "Manually" Created Elf Giving Segmentation Fault
Why Didn't I Get Segmentation Fault When Storing Past the End of the Bss
Why Does Perf Show That Sleep Takes All Cores
How to Run Multiple Tor Processes at Once with Different Exit Ips