Unix & Linux Stack Exchange
Q&A for users of Linux, FreeBSD and other Unix-like operating systems
Latest Questions
2
votes
1
answers
201
views
TTY line discipline echoing feature
I'm confused from the actual meaning of the echoing feature implemented in Linux `TTY` driver. As far as I know, a pseudo-terminal pair (`PTY` pair) consists of a `PTY` master, a `PTY` slave and a line discipline all implemented in kernel code (i.e. kernel code running in kernel space). From my unde...
I'm confused from the actual meaning of the echoing feature implemented in Linux
TTY
driver.
As far as I know, a pseudo-terminal pair (PTY
pair) consists of a PTY
master, a PTY
slave and a line discipline all implemented in kernel code (i.e. kernel code running in kernel space).
From my understanding, echoing is the feature of sending back what is written on the master side ptm
so that the process opening such a fd
(by opening the PTY
multiplexer /dev/ptmx
device file) receives back what it has written to.
My questions:
- is this echo feature implemented within the line discipline kernel code ?
- does this echo feature apply only to the PTY
master side, i.e. it doesn't
send back what is written to the PTY
slave side /dev/pts/x
?
Thanks.
CarloC
(385 rep)
Jun 21, 2025, 09:36 AM
• Last activity: Jun 23, 2025, 10:54 AM
2
votes
2
answers
56
views
Unable to write to self in graphical terminal session?
Essentially, I noticed I am unable to write to my user who is using `gnome-terminal`. `tty` returns `/dev/pts/1`, but I am unable to write there as root. Instead, it returns as follows: ``` myuser@pegasus:/$ tty /dev/pts/1 root@pegasus:/# write myuser pts/1 write: myuser is not logged in on pts/1 ``...
Essentially, I noticed I am unable to write to my user who is using
gnome-terminal
.
tty
returns /dev/pts/1
, but I am unable to write there as root. Instead, it returns as follows:
myuser@pegasus:/$ tty
/dev/pts/1
root@pegasus:/# write myuser pts/1
write: myuser is not logged in on pts/1
I have also tried write myuser tty2
, and tried not specifying the terminal, but nothing happens. How can I write to my session?
The inverse works fine:
myuser@pegasus:/$ write root pts/0
hi!
please respond
root@pegasus:/#
Message from myuser@pegasus on pts/1 at 22:05 ...
hi!
please respond
EOF
Here is what the logins look like.
root@pegasus:/# who -aT
system boot 2025-06-19 21:34
run-level 5 2025-06-19 21:34
myuser ? seat0 2025-06-19 21:34 ? 2982 (login screen)
myuser + tty2 2025-06-19 21:34 00:37 2982 (tty2)
pts/1 2025-06-19 21:41 25698 id=ts/1 term=0 exit=0
myuser@pegasus:/$ loginctl
SESSION UID USER SEAT LEADER CLASS TTY IDLE SINCE
11 0 root - 79869 manager-early - no -
2 1000 myuser seat0 2891 user tty2 no -
3 1000 myuser - 2911 manager - no -
c11 0 root - 79732 user-early pts/0 no -
4 sessions listed.
Vesta Tian
(81 rep)
Jun 19, 2025, 02:10 PM
• Last activity: Jun 21, 2025, 01:20 PM
6
votes
1
answers
2907
views
Mocking a pseudo tty (pts)
We would like to run some `curses` based apps in background. These apps use `curses` and get the current `tty` port name to be used internally to map log files and others context-terminal associations. In some tests just redirecting the input from `curses` apps that don't read the keyboard to a know...
We would like to run some
curses
based apps in background.
These apps use curses
and get the current tty
port name to be used internally to map log files and others context-terminal associations.
In some tests just redirecting the input from curses
apps that don't read the keyboard to a known pts
, worked. And so they can be executed in background, since I reserve a tty (or pseudo tty) for that.
Is it possible to mock a tty, or has a reserved pts
to some automatic running purposes, like that? We plain to launch them through crontab
.
Luciano
(1189 rep)
Jul 8, 2015, 09:10 PM
• Last activity: May 27, 2025, 12:03 PM
87
votes
8
answers
21877
views
How to trick a command into thinking its output is going to a terminal
Given a command that changes its behaviour when its output is going to a terminal (e.g. produce coloured output), how can that output be redirected in a pipeline while preserving the changed behaviour? There must be a utility for that, which I am not aware of. Some commands, like `grep --color=alway...
Given a command that changes its behaviour when its output is going to a terminal (e.g. produce coloured output), how can that output be redirected in a pipeline while preserving the changed behaviour? There must be a utility for that, which I am not aware of.
Some commands, like
grep --color=always
, have option flags to force the behaviour, but the question is how to work around programs that rely solely on testing their output file descriptor.
If it matters, my shell is bash
on Linux.
Amir
(1891 rep)
Dec 16, 2015, 01:39 PM
• Last activity: Mar 25, 2025, 03:01 PM
0
votes
0
answers
41
views
using ptys from shell
In earlier times I was able to open a pair of pseudo terminals /dev/ttyp9 and /dev/ptyp9. It was easy to do something like: `$ cat /dev/ptyp9` and in another shell `$ echo Hallo > /dev/ttyp9` But on my linux ( fedora 40 ) there is no /dev/pty... anymore :-( I found that there is something different...
In earlier times I was able to open a pair of pseudo terminals /dev/ttyp9 and /dev/ptyp9.
It was easy to do something like:
$ cat /dev/ptyp9
and in another shell
$ echo Hallo > /dev/ttyp9
But on my linux ( fedora 40 ) there is no /dev/pty... anymore :-(
I found that there is something different with device files /dev/ptmx
and /dev/pts
I was able to
$ cat /dev/ptmx
and
$ echo Hallo > /dev/pts0
which has the same effect as with the /dev/ttyp0
and /dev/ptyp0
. But if I open
/dev/ptmx
again to get a second pair of ptys I have no idea what is the corresponding device name.
The man page tells me that I have to use ptsname(). But this requires to write a c program. I want to use ptys from shell.
Is there any chance to get a pair of ptys which can be used from a shell?
Klaus
(518 rep)
Jan 21, 2025, 10:13 AM
93
votes
4
answers
28553
views
What are the responsibilities of each Pseudo-Terminal (PTY) component (software, master side, slave side)?
I am trying to figure out **how a tty works** 1 (the workflow and responsibilities of each element). I have read several interesting articles about it, but there are still some blurry areas. This is what I understand so far: * The emulated terminal makes different system calls to `/dev/ptmx`, the ma...
I am trying to figure out **how a tty works**1 (the workflow and responsibilities of each element). I have read several interesting articles about it, but there are still some blurry areas.
This is what I understand so far:
* The emulated terminal makes different system calls to
/dev/ptmx
, the master part of the pseudo terminal.
* The master part of the pseudo terminal allocates a file in /dev/pts/[0-N]
, corresponding to the obsolete serial port, and "attaches" a slave pseudo terminal to it.
* The slave pseudo terminal keeps information such as session ID, foreground job, screen size.
Here are my questions:
1. **Has ptmx** any purpose besides allocating the slave part? Does it provide **some kind of "intelligence"**, or does the emulated terminal
(xterm for instance) have all the intelligence of behaving like a
terminal?
2. **Why does xterm** have to interact with the master part, as it only forwards the stdout and stdin of the slave part? Why can't it
**directly write and read from the pts file**?
3. Is a session ID always attached to one pts file and vice versa?
Could I execute ps
and find **two session IDs for the same
/dev/pts/X**?
4. What other information does the pts
store? Does xterm update all
fields by itself, or does the ptm
add some "intelligence" to it?
----------
1. I base my understanding on the TTY demystified by Linus Åkesson , and the Linux Kernel by Andries Brouwer posts, as on several other questions on these sites
Pierre-Jean
(2279 rep)
Mar 3, 2014, 08:40 PM
• Last activity: Jan 7, 2025, 06:45 AM
0
votes
1
answers
127
views
Where is the tty line discipline exactly "logically" located?
I recently started learning about Operating Systems and the linux kernel. I was interested in terminals, so I started there, however, I quickly ran into a problem. I wrote a slightly longer question, because I wanted you to see exactly where the problem potentially arose in my understanding and know...
I recently started learning about Operating Systems and the linux kernel. I was interested in terminals, so I started there, however, I quickly ran into a problem. I wrote a slightly longer question, because I wanted you to see exactly where the problem potentially arose in my understanding and know exactly what is not clear to me. Thanks in advance :)
I have read the following articles and question/answer:
1. [The TTY demystified](https://www.linusakesson.net/programming/tty/)
2. [A Guide to the Terminal, Console, and Shell](https://thevaluable.dev/guide-terminal-shell-console/)
3. [Answer from *Stéphane Chazelas*](https://unix.stackexchange.com/a/120071/695799)
However, I'm having trouble understanding exactly where the terminal (tty) line discipline is exactly logically located because I found an inconsistency (as I naive understood it) between the 1st article and Stéphane Chazelas' answer.
[The TTY demystified](https://www.linusakesson.net/programming/tty/) first uses the following image:
It says that the TTY driver is represented through
Everything is the same, except that now we have an emulator and a virtual terminal. The only difference is that the UART driver will not be used, but the "console" driver.
The last picture shows the pseudo-terminal situation. In that case we have a master and a slave side. The terminal emulator is "pushed" into user space. Also, we have two files where the emulator interact with the master file (
Everything was working for me (or at least I think it was), and then I came across [an answer from *Stéphane Chazelas*](https://unix.stackexchange.com/a/120071/695799) :
> A lot of the intelligence is in the tty line discipline. The line
> discipline is a software module (residing in the driver, in the
> kernel) pushed on top of a serial/pty device that sits between that
> device and the line/wire (the master side for a pty).
According to images, we have a serial/console/pty "device" represented through driver in kernel (UART driver on first, emulator on second and "master side" on third picture) and then line discipline after (as part of driver, on top of it). However, next component on the pictures is TTY driver (

tty_io.c
, whereas the default Line discipline is represented through n_tty.c
. Processes (like bash) communicate with TTY driver (tty_io.c
). Actually in practice with a file that represents the entire device (UART driver + line discipline + TTY driver). UART driver is some "serial" class of driver that communicate with the physical line (and further terminal) on one side and the line discipline on the other.
Next picture from the [The TTY demystified](https://www.linusakesson.net/programming/tty/) is:

/dev/ptmx
), while processes (shell) interact with the slave file (/dev/pts/..
). In this case the pty driver is used and I would say that logically, as in the previous cases, it's at the place where "PTY master side" is written in the picture.

tty_io.c
), not line/wire as Stéphane Chazelas wrote... Maybe Stéphane thinks on TTY driver when he says "serial/pty device", but that doesn't make sense to me since then we would have, for example, UART (serial) driver line discipline TTY driver/UART (serial) driver
. Additionally, on images, TTY driver doesn't make difference between them, it is just tty_io.c
I am very confused. What am I missing? Where is the tty line discipline exactly "logically" located?
Yakog
(517 rep)
Jan 6, 2025, 11:28 PM
• Last activity: Jan 7, 2025, 02:34 AM
8
votes
1
answers
4994
views
How does the use_pty sudoers option prevent a persistence attack?
As a rule in the Debian 10 hardening guide, [and various other audit guides][1] of the Center for Internet Security (CIS), setting the `use_pty` sudoers option is recommended for the following rationale: > Attackers can run a malicious program using sudo which would fork a background process that re...
As a rule in the Debian 10 hardening guide, and various other audit guides of the Center for Internet Security (CIS), setting the
use_pty
sudoers option is recommended for the following rationale:
> Attackers can run a malicious program using sudo which would fork a background process that remains even when the main program has finished executing.
In the sudoers
man page, it is described that running a background process that retains access to the user's terminal after the main process has finished executing is no longer possible when the commands are run in a separate pseudo-terminal.
I don't really grasp the nuance here.
What does it mean to run the sudo command in a *separate pseudo-terminal*, and why is the background process attack no longer possible when this flag is set?
What other ramifications does setting use_pty
have?
Thank you!
Flo
(83 rep)
Nov 17, 2022, 12:40 PM
• Last activity: May 22, 2024, 12:19 AM
0
votes
1
answers
150
views
xterm seems to change its "home" key behaviour for emacs
In xterm, when I press the HOME key on my keyboard, it normally sends `^[[H` but when I open `emacs -nw`, it changes to `^[OH`; those are `home` and `khome` respectively. I figured out while trying to build my own terminal that `^[[H` doesn't work in emacs. However, I can't figure what causes xterm...
In xterm, when I press the HOME key on my keyboard, it normally sends
meanwhile in a different terminal (that doesn't have to be xterm), copy the emacs pty settings:
^[[H
but when I open emacs -nw
, it changes to ^[OH
; those are home
and khome
respectively. I figured out while trying to build my own terminal that ^[[H
doesn't work in emacs. However, I can't figure what causes xterm (or emacs) to change its behaviour.
Additionally
* The keys that "should" correspond to home
and khome
(the home key I usually use, and 1 on the keypad with numlock off) - always do the same thing on every terminal I have tried even though xev shows they are different, so for the rest of the question, I will treat them as the same thing.
* It doesn't seem to relate to pty settings. I have used stty -g
to copy the settings with emacs on, and then applied them with cat -v
running, and I still get the non emacs behaviour. (demo below)
* bash's readline seems to be more accepting than emacs and/or read the TERM variable, because HOME always works in bash no matter what terminal I try
----
Here are my experiments:
##### xterm
get terminal info:
$ tty
/dev/pts/1
$ echo $TERM
xterm
$ infocmp $TERM | grep home
el1=\E[1K, flash=\E[?5h$\E[?5l, home=\E[H,
kf8=\E[19~, kf9=\E[20~, khome=\EOH, kich1=\E[2~,
try the HOME key, and then return with cat -v
and then exit
$ cat -v
^[[H
^[[H
^C
open emacs
$ emacs -nw
try out behaviour of home key
(it works - I won't post a video)
use C-q
to see what the key is sending:

$ emacs_settings=$(stty -F /dev/pts/1 -g)
$ echo $emacs_settings
4001:1:bf:a31:7:7:7f:15:4:0:1:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:
and then quit emacs and start cat -v
again
$ cat -v
and then back to the second terminal - set the xterm pty back to the settings that emacs uses
$ stty -F /dev/pts/1 $emacs_settings
and press home again in xterm:
(and then press return and quit)
$ cat -v
^[[H^M
It's the same as it always is outside of emacs, the home
code, not the khome
code that somebody is helpfully inserting inside emacs.
Now if you are trying this at home, and want to quit cat -v
, you will need to use ctrl+G instead of ctrl+C because the emacs settings change some keys around. This proves the settings worked. You can also see there that there is no ^G at the end of the line from quitting, but there is a piece of carriage return - I guess because the echo settings changed, and it's in raw mode.
Here are the human readable emacs pty settings if you are curious.
$ stty -F /dev/pts/1 -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^G; quit = ^G; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; swtch = ; start = ; stop = ; susp = ;
rprnt = ; werase = ; lnext = ; discard = ; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig -icanon -iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
----
Other terminals
##### linux
$ infocmp linux | grep home
home=\E[H, hpa=\E[%i%p1%dG, ht=^I, hts=\EH, ich=\E[%p1%d@,
kf8=\E[19~, kf9=\E[20~, khome=\E[1~, kich1=\E[2~,
this one isn't easy to take a screenshot (I could photograph it but I haven't)
The summary is - whether you are in emacs or not, the HOME key sends khome
from the terminal settings, and it always works in emacs.
##### MATE Terminal (xterm-256color
)
$ echo $TERM
xterm-256color
$ infocmp $TERM | grep home
el1=\E[1K, flash=\E[?5h$\E[?5l, home=\E[H,
kf8=\E[19~, kf9=\E[20~, khome=\EOH, kich1=\E[2~,
$ cat -v
^[[H
^[[H
^C
but again it sends ^[OH
inside emacs! So again they are different. I don't know how I missed this before. I guess MATE terminal implements exactly what xcode does, or uses some of the same components.
On the other hand:
##### Hyper (xterm-256color
)
In this case, they just send khome
all the time, and the HOME key still seems to work how you would expect it to work.
$ echo $TERM
xterm-256color
$ cat -v
^[OH
^[OH
^C
$ emacs -nw
$ # ... ^[OH again
##### tmux (in MATE terminal) screen
I don't know when tmux sets TERM
to screen
and when it sets it to tmux
, but today on this computer, in this host terminal, it's screen
.
$ echo $TERM
screen
$ infocmp $TERM | grep home
enacs=\E(B\E)0, flash=\Eg, home=\E[H, hpa=\E[%i%p1%dG,
khome=\E[1~, kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~,
$ cat -v
^[[1~
^[[1~
^C
$ emacs -nw
$ # also ^[[1~ with C-q inside emacs
------
##### round-up
* Some terminals just send khome
all the time, while others manage to send khome
inside emacs and home
the rest of the time.
* khome
and home
both work for bash readline, but only khome
works in emacs - or there is just a fixed list of home keys that work in emacs (I am talking about default config) - I am leaning toward the fixed list since I can't get emacs behaviour to change by changing TERM
##### the big question
How xterm (and MATE Terminal) manages to change which code it sends when emacs is open.
Here are some guesses I can think of:
a) xterm has a special rule emacs
b) emacs has a special rule about xterm
c) emacs does change the terminal settings to cause this, but whatever that setting is, cat
continually changes back if you try to make cat use that setting
##### smaller questions worth mentioning
* Why don't the keys that look like they correspond to home
and khome
send the corresponding values?
* Does emacs (by default) change its behaviour based on TERM
?
Alex028502
(643 rep)
Apr 13, 2024, 05:40 PM
• Last activity: Apr 14, 2024, 05:16 AM
0
votes
2
answers
179
views
How can I connect a bash process to a tty _without_ using getty
I would have two serial usb devices connected to each other, `/dev/ttyUSB1` and `/dev/ttyUSB2`. I would like to run `/bin/bash` connected to one end, so that I can attach to the other end using `picocom` and use picocom as a local terminal emulator. I have tried stuff like this ``` setsid /bin/bash...
I would have two serial usb devices connected to each other,
/dev/ttyUSB1
and /dev/ttyUSB2
. I would like to run /bin/bash
connected to one end, so that I can attach to the other end using picocom
and use picocom as a local terminal emulator.
I have tried stuff like this
setsid /bin/bash /dev/ttyUSB2 2>&1
and then connecting to the other end with picocom, but I just get a screen full of gibberish (:~$ 0m:~$ 0m:~$ 0m:~$ 0m:~$ 0m:~$ 0m:~$ 0m:~$ 0m:~$ 0m:~$ 0m:~$ 0m:~$ 0m:~$ 0m:~$ 0m:~$
).. (the baud rates match, and the two terminals can communicate with two picocom on both ends)
However, I really have no idea what I am doing. Can anybody tell me the secret?
-----
Correction/Update:
On a different computer, I not longer get the gibberish I was getting before. When I connect bash to one tty as above, and connect to the other end with picocom, I get the prompt now, and I can run commands, but my commands don't get echoed back to me (I only see the result), and I don't have "job control" (which I test with Ctrl+C, which will not stop a sleep process)
-----
Background:
I have already successfully use picocom as a local terminal emulator in two other ways:
1. with getty:
sudo systemctl start getty@ttyUSB2.service
allows me to connect to /dev/ttyUSB1
with picocom successfully, but I have to log in.
(thanks to this answer https://unix.stackexchange.com/a/772040/158192 to a previous question)
1. with socat
$ socat -d -d PTY,raw,echo=0 EXEC:"/bin/bash",pty,stderr,setsid,sane
2024/04/01 18:32:13 socat N PTY is /dev/pts/4
...
which allows me to use picocom as a local terminal like this picocom /dev/pts/4
---
so yeah I should be able to connect /bin/bash to the usb tty myself right? but my trials all have errors.
Alex028502
(643 rep)
Apr 1, 2024, 04:50 PM
• Last activity: Apr 8, 2024, 05:23 PM
2
votes
1
answers
2813
views
trying to make my own shell handle ctrl+c properly
I am trying to understand how shells are set up so that the programs they are running receive the SIGINT when you press ctrl C but the shell doesn't, because when you are running bash, and run another program inside, and then you press CTRL+C, the program you are running stops but bash doesn't. This...
I am trying to understand how shells are set up so that the programs they are running receive the SIGINT when you press ctrl C but the shell doesn't, because when you are running bash, and run another program inside,
and then you press CTRL+C, the program you are running stops but bash doesn't.
This even applies when you start bash from within another shell.
I tried to make my own special shell program which just runs a single child
program when you press any key.
#! /usr/bin/env bash
set -e
while true
do
echo press any key to run $@
read -n 1 -r -s key
code=$(echo $key | cat -v)
if [[ "$code" == "^D" ]]
then
echo bye
exit 0
fi
echo running $@
$@ || echo oops
done
This is what it does:
$ ./shell.sh sleep 1
press any key to run sleep 1
running sleep 1
press any key to run sleep 1
running sleep 1
press any key to run sleep 1
bye
press any key and it runs the program you passed in as arguments, and press
ctrl+d at the prompt to exit
However, if I try to stop the sleep program with ctrl+c:
$ ./shell.sh sleep 10
press any key to run sleep 10
running sleep 10
^C
$
it stops the shell program as well - which is expected.
However, when you run bash
on its own, it doesn't behave like that.
I would like mine to work like interactive bash - allow the "sleep" command to exit, and then continue to the prompt.
I have tried running it with -m
as well, just in case that's the trick:
$ bash -m shell.sh sleep 10
press any key to run sleep 10
running sleep 10
^C$
but it exits as well.
So I have two questions: (that might have the same answer)
- How can I tell bash to behave as if it were running interactively, and not
exit when I press ctrl+c and just allow the child program to terminate and go
continue to the prompt.
- What is bash doing internally? For example when I want to make the same
shell program in python (I have done that as well, but it's not included here)
what do I have to do since it won't have the bash option that will probably
answer the above. I know I can make it work by handing the signal, but I would
like to know that I am doing it the same way that a real shell does it.
I think I could make it work by handling signals in my "shell" but something tells me that's not how real shells work - and I keep hearing stuff about foreground, and groups - so I am hoping that can just be inserted into my example - or at least that there is an explanation about why it can't be inserted into my example.
Alex028502
(643 rep)
Oct 3, 2023, 07:44 PM
• Last activity: Mar 28, 2024, 06:38 AM
1
votes
1
answers
151
views
job control doesn't work when I create my own pty pair with socat
I am experimenting with understanding terminal emulators by looking at the different pieces of the puzzle. I am trying to start a pty pair and shell process with socat, and then connect to it with picocom. This is what I have figured out for the socat command: ``` $ socat -d -d PTY,raw,echo=0 EXEC:"...
I am experimenting with understanding terminal emulators by looking at the different pieces of the puzzle.
I am trying to start a pty pair and shell process with socat, and then connect to it with picocom.
This is what I have figured out for the socat command:
$ socat -d -d PTY,raw,echo=0 EXEC:"/bin/sh",pty,stderr,setsid,sane
2024/03/12 08:12:16 socat N PTY is /dev/pts/5
2024/03/12 08:12:16 socat N forking off child, using pty for reading and writing
2024/03/12 08:12:16 socat N forked off child process 9107
2024/03/12 08:12:16 socat N forked off child process 9107
2024/03/12 08:12:16 socat N starting data transfer loop with FDs [5,5] and [7,7]
2024/03/12 08:12:16 socat N execvp'ing "/bin/sh"
and now try to connect with picocom. It seems to work, but signals don't work.
$ picocom /dev/pts/5
picocom v3.1
port is : /dev/pts/5
flowcontrol : none
baudrate is : 9600
parity is : none
databits are : 8
stopbits are : 1
escape is : C-a
local echo is : no
noinit is : no
noreset is : no
hangup is : no
nolock is : no
send_cmd is : sz -vv
receive_cmd is : rz -vv -E
imap is :
omap is :
emap is : crcrlf,delbs,
logfile is : none
initstring : none
exit_after is : not set
exit is : no
Type [C-a] [C-h] to see available commands
Terminal ready
$ tty # make sure I'm hooked up to the right thing
/dev/pts/6
$ sleep 10 # see if signals are working
^C$ sh # signals are not working - so opening a new shell which will show the error message that picocom hid
sh: 0: can't access tty; job control turned off
$
here are the terminal settings from a third terminal in case that helps
$ stty -a -F /dev/pts/5
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
$ stty -a -F /dev/pts/6
speed 38400 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
I had a similar problem when setting up getty last experiment:
https://unix.stackexchange.com/questions/772034
The problem there was that getty doesn't like to run inside an existing tty. Is it the same problem here? Is there a way to tell socat not to run inside a tty? Terminal emulators that set up a shell process aren't using systemd, so how do they do it? and how can I do the same thing that terminal emulators do to set up a shell process that I can connect to?
----
update:
I have tried running socat in systemd just in case, and the result was the same.
-----
answer to a comment:
this is with the socat command running in systemd
$ ps j $$
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
16170 16171 16170 16170 ? -1 S 1000 0:00 /bin/sh
and this is with socat running in the foreground in another terminal
$ ps j $$
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
19215 19216 19216 19216 ? -1 Ss 1000 0:00 /bin/sh
$ tty
/dev/pts/11
(10/11 is the pair that I created with the socat command)
----
There has been a bit of a twist. This only happens with dash
. If you put in bash
instead, or even bash --noediting --posix
or ln -s /bin/bash sh
and then use that sh
to turn on posix mode, job control seems to work. And if you go into bash first, and then open dash from there, job control works, but if you open dash originally, and then open bash from inside dash, it doesn't work. The terminal settings are the same as long as you choose --noediting
. So there must be something different about how dash starts up.
Alex028502
(643 rep)
Mar 12, 2024, 07:24 AM
• Last activity: Mar 12, 2024, 09:10 PM
0
votes
1
answers
125
views
how to get file descriptors of PTY inside of a child?
https://man7.org/linux/man-pages/man7/pty.7.html in the "UNIX 98 pseudoterminals" it is said that `ptsname` can be used (and then `open`), but this function accepts file descriptor. i tried to put 0 (STDIN) and 1 (STDOUT) in there, but it fails with "Inappropriate ioctl for device". im running my pr...
https://man7.org/linux/man-pages/man7/pty.7.html
in the "UNIX 98 pseudoterminals" it is said that
ptsname
can be used (and then open
), but this function accepts file descriptor. i tried to put 0 (STDIN) and 1 (STDOUT) in there, but it fails with "Inappropriate ioctl for device". im running my program from gnome-terminal
im not writing another xterm
program. just want to have file descriptors for asynchronous (non-blocking) non-canonical low-level input and output.
Michael Quad
(103 rep)
Feb 16, 2024, 01:55 AM
• Last activity: Feb 19, 2024, 06:17 PM
0
votes
1
answers
293
views
Pseudo-terminals control each other, how to get the return display
The problem is: my pseudo-terminal is /dev/pts/0, the target pseudo-terminal is /dev/pts/4, and I'm trying to get the target pseudo-terminal to print text using the echo text > /dev/pts/4 command. So the first question is: after I use echo text > /dev/pts/4 command, the target host does display the...
The problem is: my pseudo-terminal is /dev/pts/0, the target pseudo-terminal is /dev/pts/4, and I'm trying to get the target pseudo-terminal to print text using the echo text > /dev/pts/4 command.
So the first question is: after I use echo text > /dev/pts/4 command, the target host does display the text back, but one disadvantage is that the target will display another line after displaying the text back, and you have to manually press ctrl + c to end it, how can I avoid the above situation?
Secondly, I think after using man pty > /dev/pts/4, the target pseudo-terminal does open a pty manual, but the downside is that my pseudo-terminal also produces a blank line after the text is displayed, and no matter how much I try to end it with ctrl + c, it doesn't work, and the only way to fix it is to just shut down my pseudo-terminal. So I tried running man pty > /dev/pts/4 & in the background again, and my pseudo-terminal didn't show the blank line, but the target pseudo-terminal didn't show the man manual.
So the second problem is: how to make the target pseudo-terminal display the man manual normally, but my pseudo-terminal doesn't display the blank line carriage return.
The last problem is that I want to intercept all displays of the target pseudo-terminal.
There are a lot of questions and descriptions, thanks for your answers!
xnl2d
(17 rep)
Feb 1, 2024, 02:24 PM
• Last activity: Feb 1, 2024, 04:42 PM
2
votes
0
answers
857
views
How to suppress "Failed to set controlling terminal" warning in GDB when setting program to run on another terminal?
I'm using GDB to debug a program, and I want to direct its output to a different terminal than the one where GDB is running. Here's what I've been doing: 1. Open a second terminal, check its device name using `tty`, and get something like `/dev/pts/14`. 2. In my GDB session, I use the command `tty /...
I'm using GDB to debug a program, and I want to direct its output to a different terminal than the one where GDB is running. Here's what I've been doing:
1. Open a second terminal, check its device name using
tty
, and get something like /dev/pts/14
.
2. In my GDB session, I use the command tty /dev/pts/14
to set the output to that terminal.
3. Then I issue the run
command in GDB to start the program.
This setup does correctly direct the output to terminal 2, but the problem is that the first line on terminal 2 always says:
warning: GDB: Failed to set controlling terminal: Operation not permitted
I tried running GDB as root using sudo
but encountered the same warning. Here's a simplified representation of my process:
# Terminal 2:
$ tty
/dev/pts/14
# Terminal 1:
$ gdb ./some-program
(gdb) tty /dev/pts/14
(gdb) run
Would anyone be able to explain what's causing this warning and how I could resolve or suppress it? What does GDB attempt to do when setting the controlling terminal, and why is it failing?
**Note:** Same things happens on a classic tty like /dev/tty3
Sebastian Carlos
(262 rep)
Dec 9, 2023, 07:26 PM
• Last activity: Dec 9, 2023, 07:31 PM
0
votes
0
answers
233
views
How to reown a process?
when i run this script with a shortcut(sxhkd): #!/bin/sh MUSIC_DIR="$HOME/music" songs=$(ls "$MUSIC_DIR") filename=$( echo -e "random\n$songs" | dmenu -l 30 -i -p "Play >> ") if [[ $filename = "random" ]] then filename=$(ls "$MUSIC_DIR" |shuf -n 1) fi if [[ -f "$MUSIC_DIR/$filename" ]] then notify-s...
when i run this script with a shortcut(sxhkd):
#!/bin/sh
MUSIC_DIR="$HOME/music"
songs=$(ls "$MUSIC_DIR")
filename=$( echo -e "random\n$songs" | dmenu -l 30 -i -p "Play >> ")
if [[ $filename = "random" ]]
then
filename=$(ls "$MUSIC_DIR" |shuf -n 1)
fi
if [[ -f "$MUSIC_DIR/$filename" ]]
then
notify-send -t 2500 "$filename is playing" && mpv "$MUSIC_DIR/$filename" --no-audio-display
else
notify-send -t 1500 "typo?"
fi
I want to open a terminal control mpv process on it ( get the mpv terminal interface ).
I have tried reptyr, but I'm getting this error.
~ λ reptyr $(pgrep mpv)
[-] Process 514610 (dmenuMusic) shares 514636's process group. Unable to attach.
(This most commonly means that 514636 has sub-processes).
Unable to attach to pid 514636: Invalid argument
also tried:
~ λ echo 0 | doas tee /proc/sys/kernel/yama/ptrace_scope
It just didn't work, gave me same error.
white-hat-er
(117 rep)
Nov 18, 2023, 06:44 PM
• Last activity: Nov 18, 2023, 11:30 PM
0
votes
1
answers
314
views
how can I make socat simulate unplugging a serial device
I have this test program ``` import sys for line in sys.stdin: print(line.strip()) print("DONE") ``` if I get it to print out lines from a real device (an FTDI) ``` python3 demo.py > ttyFake.interface ``` and they get printed but if I stop the socat process with SIGINT or SIGTERM I get something lik...
I have this test program
import sys
for line in sys.stdin:
print(line.strip())
print("DONE")
if I get it to print out lines from a real device (an FTDI)
python3 demo.py > ttyFake.interface
and they get printed
but if I stop the socat process with SIGINT or SIGTERM I get something like this:
$ python3 demo.py
for line in sys.stdin:
OSError: [Errno 5] Input/output error
I have also tried this with no luck:
$ echo -ne '\004' >> ttyFake.interface # send ^D
Is there any way to make socat simulate the unplugging behaviour? Do I just need a better way to send a ^D
?
Subquestion:
I don't really know if ^D
is what the process detects in stdin to determine that input has finished, or just what you send to your terminal emulator to end the input.
Alex028502
(643 rep)
Oct 27, 2023, 04:15 PM
• Last activity: Oct 30, 2023, 07:48 AM
30
votes
4
answers
7677
views
How can we know who's at the other end of a pseudo-terminal device?
If I do a: echo foo > /dev/pts/12 Some process will read that `foo\n` from its file descriptor to the master side. Is there a way to find out what that(those) process(es) is(are)? Or in other words, how could I find out which xterm/sshd/script/screen/tmux/expect/socat... is at the other end of `/dev...
If I do a:
echo foo > /dev/pts/12
Some process will read that
foo\n
from its file descriptor to the master side.
Is there a way to find out what that(those) process(es) is(are)?
Or in other words, how could I find out which xterm/sshd/script/screen/tmux/expect/socat... is at the other end of /dev/pts/12
?
lsof /dev/ptmx
will tell me the processes that have file descriptors on the master side of any pty. A process itself can use ptsname()
(TIOCGPTN
ioctl) to find out the slave device based on its own fd to the master side, so I could use:
gdb --batch --pid "$the_pid" -ex "print ptsname($the_fd)"
for each of the pid/fd returned by lsof
to build up that mapping, but is there a more direct, reliable and less intrusive way to get that information?
Stéphane Chazelas
(579282 rep)
Jun 11, 2014, 08:12 PM
• Last activity: Oct 19, 2023, 07:30 AM
0
votes
1
answers
161
views
Can I set up a serial terminal (RS-232) without a pty?
I have two computers that both have a RS-232 port on `/dev/ttyS0` connect together with a null modem. I am trying to understand bit by bit how an external terminal worked in the old days, and how that relates to how linux works today. I have gotten it to work like this: main computer: ``` $ sudo soc...
I have two computers that both have a RS-232 port on
/dev/ttyS0
connect together with a null modem.
I am trying to understand bit by bit how an external terminal worked in the old days, and how that relates to how linux works today.
I have gotten it to work like this:
main computer:
$ sudo socat /dev/ttyS0,raw,echo=0 exec:"/bin/bash -i",pty,stderr,setsid,sigint,sane
terminal:
picocom -b 9600 /dev/ttyS0
However, that has pty
in it - which is why I get this on the terminal:
# tty
/dev/pts/11
and you shouldn't need a pseudo tty if you have an actual real life tty should you? I mean they were connecting terminals in with wires before they had pseudo anything weren't they?
So I have been trying to mix and match socat options to make it with with no pty, but with no luck. If I can anything appears in my terminal computer, there are no carriage returns or job control and tty
says "not a tty".
I have to admit I don't understand the socat syntax (or terminal settings) - I was hoping to see the correct answer, and understand the syntax from there.
Could somebody either tell me how to make a remote terminal with no pty, or help me accept that it's not possible?
Alex028502
(643 rep)
Oct 4, 2023, 08:16 AM
• Last activity: Oct 4, 2023, 08:47 PM
0
votes
1
answers
605
views
How to determine the graphical tty in loginctl
Loginctl lists a lot of sessions, and I want programmatically to know which one is a graphical session (e.g. GNOME desktop). In the example below, I have a GNome desktop session open, an ssh connection open, and a text session (getty) open. ``` $ loginctl SESSION UID USER SEAT TTY 3 1000 user seat0...
Loginctl lists a lot of sessions, and I want programmatically to know which one is a graphical session (e.g. GNOME desktop).
In the example below, I have a GNome desktop session open, an ssh connection open, and a text session (getty) open.
$ loginctl
SESSION UID USER SEAT TTY
3 1000 user seat0 tty2
237 1000 user pts/2
260 1000 user seat0 tty3
3 sessions listed.
$
I can guess that tty2 is the GNome session, because I can switch to it using Ctrl+Alt+F2.
tty3 is the text session (Ctrl+Alt+F3). pts/2 is the remaining ssh session. However, how can a program know which one is which?
Note: I don't think the following ways are solutions, because they are not rigorous. The user can probably open a new tty and run /usr/libexec/gdm-x-session, which will trick my program
Method 1: run ps -aux | grep /usr/libexec/gdm-x-session
, see:
... tty2 Sl+ 00:32 0:00 /usr/libexec/gdm-x-session
Method 2: Run lsof /dev/tty2
, see:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
gdm-x-ses 3271 user 0u CHR 4,2 0t0 23 /dev/tty2
...
Eric Stdlib
(559 rep)
Sep 15, 2023, 03:13 PM
• Last activity: Sep 15, 2023, 03:29 PM
Showing page 1 of 20 total questions