当我需要在终端 shell 可用时配置终端线路设置时,我使用stty
.
当我将调试器附加到正在运行诅咒的进程时,当前的 tty 设置会妨碍调试器的运行(回显关闭,换行符不会被翻译)。我希望能够打开echo
和onlcr
,以便我可以正确使用调试器 ( pdb
)。
当我暂停这个进程(Ctrl
+ z
)来检查控制设置时stty
,这些终端设置没有改变。我认为诅咒可以在挂起/恢复信号时保存/恢复这些设置。
有没有办法使用活动进程远程设置终端设置,而无需挂起到父 shell?
答案1
进程的 stdout 是一个文件描述符,可用作 UNIX 系统上某处的路径。我们需要找到此路径来设置其 tty 属性。由于这是curses,因此该文件描述符将指向终端设备(pts/tty)。
第一步是找到正在运行的进程的pid。使用pidof
、pgrep
、 或ps aux
:
ps aux | grep '<program arguments>'
获得正在运行的进程的 pid 后,您可以使用proc
(如果可用)或找到附加到该进程的终端设备的路径lsof
。
使用以下命令获取 tty/pts 路径lsof
:
device="$(lsof -X -p <pid> | grep -o '/dev/.*' | grep -v urandom | uniq)"
这会给你类似的东西:
device=/dev/pts/4
在这里,我们使用-X
忽略 TCP 连接的选项来阻止 lsof 挂起,并-p
告诉 lsof 它正在被赋予一个pid
.
如果/proc
可用(linux),那么您可以在其 pid 下找到一个符号链接:
device=/proc/<pid>/fd/1
现在我们知道了输出设备,我们可以设置它的 tty 属性:
stty onlcr echo icrnl icanon -F $device
默认情况下 stty 设置当前终端标准输入的 tty 属性。您可以使用 -F 指定路径。
现在由于某种原因我必须多次设置这些属性才能让它们坚持下去:
while true; do stty onlcr echo icrnl icanon -F /proc/<pid>/fd/1; done
注意:写完这篇文章后,我意识到ps
可以在进程旁边列出附加的 TTY:ps ao args,tty
。