标签: pty

困惑于Docker -t选项以分配伪TTY

这个选项到底是做什么的?我一直在读TTY,但我仍然感到困惑.我玩的没有-t和只是-i,似乎期望用户输入的程序抛出错误没有-t.为什么启用伪TTY很重要?

tty pty docker

177
推荐指数
6
解决办法
4万
查看次数

如何在通道0上修复请求失败

当我想连接到我的服务器这样的时候

ssh -a username@my-server.de -p 22
Run Code Online (Sandbox Code Playgroud)

它给了我两个错误消息:

PTY allocation request failed on channel 0
shell request failed on channel 0
Run Code Online (Sandbox Code Playgroud)

当我使用参数时-T,第一个错误消息消失了.但是如何修复第二个呢?我无法连接.对于其他服务器,我可以毫无问题地连接.

我在MAC OS 10.9上参数-v显示了这个调试输出:

OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011
debug1: Reading configuration data /etc/ssh_config
debug1: /etc/ssh_config line 20: Applying options for *
debug1: Connecting to xxx.your-server.de [188.40.3.15] port 22.
debug1: Connection established.
debug1: identity file /Users/xxx/.ssh/id_rsa type -1
debug1: identity file /Users/xxx/.ssh/id_rsa-cert type -1
debug1: identity file /Users/xxx/.ssh/id_dsa type -1
debug1: identity file /Users/xxx/.ssh/id_dsa-cert type …
Run Code Online (Sandbox Code Playgroud)

ssh terminal pty

67
推荐指数
8
解决办法
20万
查看次数

你可以愚弄isatty并分别记录stdout和stderr吗?

问题

因此,您希望记录进程或子进程的stdout和stderr(单独),如果您没有记录任何内容,则输出与您在终端中看到的不同.

看起来很简单没有?不幸的是,看起来可能无法为这个问题编写一个通用的解决方案,这个解决方案适用于任何给定的流程......

背景

管道重定向是一种分离stdout和stderr的方法,允许您单独记录它们.不幸的是,如果将stdout/err更改为管道,则进程可能会检测到管道不是tty(因为它没有宽度/高度,波特率等)并且可能会相应地更改其行为.为什么改变行为?好吧,一些开发人员利用终端的功能,如果您要写入文件,这些功能没有意义.例如,加载条通常要求将终端光标移回到行的开头,并使用新长度的条覆盖前一个加载条.颜色和字体粗细也可以显示在终端中,但是在平面ASCII文件中它们不能.如果您要将这样的程序的stdout直接写入文件,那么该输出将包含所有终端ANSI转义码,而不是正确格式化的输出.因此,开发人员在向stdout/err写入任何内容之前会执行某种"isatty"检查,因此如果该检查返回false,它可以为文件提供更简单的输出.

这里通常的解决方案是通过使用pty来欺骗这些程序,使管道实际上是ttys - 一个也具有宽度,高度等的双向管道.你将进程的所有输入/输出重定向到这个pty,这就是欺骗进程思考它与真实终端的对话(你可以直接将其记录到文件中).唯一的问题是,通过对stdout和stderr使用单个pty,我们现在无法再区分这两者.

所以你可能想为每个管道尝试不同的pty - 一个用于stdin,一个用于stdout,一个用于stderr.虽然这将在50%的时间内工作,但不幸的是,许多进程会执行额外的重定向检查,以确保stdout和stderr(/ dev/tty000x)的输出路径相同.如果它们不是,则必须有重定向,因此它们会给你相同的行为,就好像你没有pty管道stderr和stdout一样.

您可能认为这种过度检查重定向并不常见,但不幸的是它实际上非常普遍,因为许多程序重用其他代码进行检查,就像在OSX中找到的这些代码一样:

http://src.gnu-darwin.org/src/bin/stty/util.c

挑战

我认为找到解决方案的最佳方式是挑战.如果任何人都可以运行以下脚本(理想情况下通过Python,但此时我将采取任何措施),以便单独记录stdout和stderr,并且你设法欺骗它认为它是通过tty执行的,你解决了问题:)

#!/usr/bin/python

import os
import sys

if sys.stdout.isatty() and sys.stderr.isatty() and os.ttyname(sys.stdout.fileno()) == os.ttyname(sys.stderr.fileno()):
    sys.stdout.write("This is a")
    sys.stderr.write("real tty :)")
else:
    sys.stdout.write("You cant fool me!")

sys.stdout.flush()
sys.stderr.flush()
Run Code Online (Sandbox Code Playgroud)

请注意,解决方案应该适用于任何进程,而不仅仅是此代码.覆盖sys/os模块并使用LD_PRELOAD是击败挑战的非常有趣的方法,但它们并没有解决问题的核心:)

python unix linux tty pty

35
推荐指数
2
解决办法
2013
查看次数

如果未在父级中关闭,则slave pty上的最终输出将丢失.为什么?

我编写并维护了一个程序rlwrap,它使用伪终端与子进程通信. 在所有Unix(类似)系统中都可以找到伪终端(ptys),但它们在不同平台上的表现略有不同.

例证:在rlwrap,父进程保持slave pty打开以密切关注子进程的终端设置(在Linux和FreeBSD上可以使用master,例如在Solaris中)

在FreeBSD(8.2)(但不是Linux)上,这会导致孩子的最终输出丢失.例如:

#include <stdio.h>

/* save as test.c and compile with gcc -o test test.c -lutil */

#define BUFSIZE 255

int main(void) {
  int master, slave;
  char buf[BUFSIZE];
  int nread;

  openpty(&master, &slave, NULL, NULL, NULL);

  if (fork()) {       /* parent:                                                      */
    close(slave);     /* leave this out and lose slave's final words ... WHY?         */
    do {
      nread = read(master, buf, BUFSIZE);
      write(STDOUT_FILENO, buf, nread); /* echo child's output to stdout              */ …
Run Code Online (Sandbox Code Playgroud)

c unix portability freebsd pty

30
推荐指数
1
解决办法
1622
查看次数

与终端 pty 主机进程的连接无响应

安装 VSCode 后,我开始收到这个特定的通知:

与终端 pty 主机进程的连接无响应,终端可能停止工作。

截屏

在我单击重新启动按钮之前,通知不会消失。但是,尽管单击此按钮,但没有发生任何变化,并且几秒钟后再次弹出通知。

这个问题导致我的终端停止工作并且无法运行节点应用程序。

pty visual-studio-code

24
推荐指数
4
解决办法
2万
查看次数

检测子进程何时等待输入

我正在编写一个Python程序,用于在Linux服务器上运行用户上传的任意(因此,在最坏的情况下,不安全,错误和崩溃)代码.抛开安全问题,我的目标是确定代码(可能是任何语言,编译或解释)是否写入了正确的内容stdout,stderr以及给定输入的其他文件是否输入到程序中stdin.在此之后,我需要向用户显示结果.

目前的解决方案

目前,我的解决办法是使用产卵子进程subprocess.Popen(...)与文件句柄stdout,stderrstdin.后面的文件stdin句柄包含了操作过程中的程序读取输入,并且该程序已终止后,将stdoutstderr文件的读取,并检查正确性.

问题

这种方法非常完美,但是当我显示结果时,我无法组合给定的输入和输出,因此输入将出现在与从终端运行程序时相同的位置.即类似的程序

print "Hello."
name = raw_input("Type your name: ")
print "Nice to meet you, %s!" % (name)
Run Code Online (Sandbox Code Playgroud)

stdout运行后,包含该程序的文件的内容将是:

Hello.
Type your name: 
Nice to meet you, Anonymous!
Run Code Online (Sandbox Code Playgroud)

鉴于内容包含该文件stdinAnonymous<LF>.所以,简而言之,对于给定的示例代码(以及,等效地,对于任何其他代码),我想实现如下结果:

Hello.
Type your name: Anonymous
Nice to meet you, Anonymous!
Run Code Online (Sandbox Code Playgroud)

因此,问题是检测程序何时等待输入.

尝试过的方法

我尝试了以下方法来解决问题:

Popen.communicate(...)

这允许父进程沿管道单独发送数据,但只能调用一次,因此不适用于具有多个输出和输入的程序 - 正如可以从文档中推断出来的那样.

直接从Popen.stdout …

python linux subprocess pty unbuffered-output

23
推荐指数
1
解决办法
3440
查看次数

将数据管道到需要TTY(终端)的Linux程序

我在Linux中有一个程序,如果它的stdin/stdout不是TTY(终端设备),它就拒绝运行.是否有一个易于使用的工具,它将创建一个PTY,使用新创建的TTY启动程序,并通过stdin/stdout复制所有数据?

用例不是交互式的,而是脚本的.我正在寻找最轻量级的解决方案,最好不要创建TCP连接,也不需要安装太多其他工具和库.

linux terminal pipe tty pty

20
推荐指数
1
解决办法
5860
查看次数

如果分配了伪tty,为什么在ssh上运行后台任务会失败?

在ssh上运行命令时,我最近遇到了一些奇怪的行为.我有兴趣听到下面这种行为的任何解释.

正在运行ssh localhost 'touch foobar &'创建一个名为expect的文件foobar:

[bob@server ~]$ ssh localhost 'touch foobar &'
[bob@server ~]$ ls foobar
foobar
Run Code Online (Sandbox Code Playgroud)

但是,运行相同的命令但使用-t强制伪tty分配选项无法创建foobar:

[bob@server ~]$ ssh -t localhost 'touch foobar &'
Connection to localhost closed.
[bob@server ~]$ echo $?
0
[bob@server ~]$ ls foobar
ls: cannot access foobar: No such file or directory
Run Code Online (Sandbox Code Playgroud)

我目前的理论是,由于触摸过程正在被覆盖,因此伪进程在进程有机会运行之前被分配和未分配.当然,添加一秒睡眠可让触摸按预期运行:

[bob@pidora ~]$ ssh -t localhost 'touch foobar & sleep 1'
Connection to localhost closed.
[bob@pidora ~]$ ls foobar
foobar
Run Code Online (Sandbox Code Playgroud)

如果有人有明确的解释,我会非常有兴趣听到它.谢谢.

ssh bash jobs tty pty

17
推荐指数
1
解决办法
3557
查看次数

运行命令并像在终端中一样近乎实时地获取它的stdout,stderr

我试图在Python中找到一种方法来运行其他程序:

  1. 正在运行的程序的stdout和stderr可以单独记录.
  2. 正在运行的程序的stdout和stderr可以近乎实时地查看,这样如果子进程挂起,用户就可以看到.(即我们不会在将stdout/stderr打印到用户之前等待执行完成)
  3. 奖励标准:正在运行的程序不知道它是通过python运行的,因此不会做意想不到的事情(比如chunk它的输出而不是实时打印,或退出因为它需要终端查看其输出) .这个小标准几乎意味着我们需要使用我认为的pty.

这是我到目前为止所得到的...方法1:

def method1(command):
    ## subprocess.communicate() will give us the stdout and stderr sepurately, 
    ## but we will have to wait until the end of command execution to print anything.
    ## This means if the child process hangs, we will never know....
    proc=subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, executable='/bin/bash')
    stdout, stderr = proc.communicate() # record both, but no way to print stdout/stderr in real-time
    print ' ######### REAL-TIME ######### '
    ########         Not Possible
    print ' ########## RESULTS ########## …
Run Code Online (Sandbox Code Playgroud)

python subprocess tty pexpect pty

15
推荐指数
1
解决办法
3702
查看次数

Ruby on Linux PTY在没有EOF的情况下消失,引发了Errno :: EIO

我正在编写一些带有文件的代码,将该文件传递给多个二进制文件之一进行处理,并监视转换过程中的错误.我已经在OSX上编写并测试了以下例程,但linux因为我不清楚的原因而失败了.

#run the command, capture the output so it doesn't display
PTY.spawn(command) {|r,w,pid|
    until r.eof? do
      ##mark
      puts r.readline
    end
}
Run Code Online (Sandbox Code Playgroud)

运行的命令变化很大,##标记处的代码已简化为本地回显以尝试调试问题.该命令执行,脚本在终端中打印预期的输出,然后抛出异常.

它在Debian系统上产生的错误是: Errno::EIO (Input/output error - /dev/pts/0):

我可以提出的所有命令字符串都会产生错误,当我运行没有本地echo块的代码时,它运行得很好:

PTY.spawn(command) {|r,w,pid|}
Run Code Online (Sandbox Code Playgroud)

在任何一种情况下,命令本身执行正常,但似乎debian linux没有发送eof up the pty.PTY文档页面和ruby-doc上的IO似乎没有任何帮助.

有什么建议?谢谢.

-vox-

ruby debian pty ruby-1.9.3

14
推荐指数
2
解决办法
4632
查看次数