问题标签 [pty]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 如何制作一个允许输入 SSH 密码的类似 shell 的程序?
在 OSX 终端上,我可以使用 SSH 连接到服务器,因为终端提供密码输入会话。
我想做自己的终端实现,所以我
- 创建了伪终端。
- 叉
- 将 pty slave 重定向到子进程的标准输入。
- 执行 bash。
然后,将字符串推ssh user@server.com
送到父进程的 pty master 中。但是通过程序向我展示了这一点。
而不是密码会话。
我的问题是什么,我该如何解决?
PS我知道我可以使用expect
实用程序。这只是实现我自己的伪 shell 应用程序的试验。
更新供以后参考
解决方案的关键是使用forkpty()
函数而不是posix_openpt()
函数。前者处理所有烦人的工作,并给我双向主文件编号。我可以读取和写入文件号。并且创建的 pty 设备完美运行。SSH 登录会话运行良好。相比之下,后者仍然需要很多我永远无法弄清楚的作品。
我必须关心forkpty
最后两个参数。我以为它们是输出,但实际上是输入。那是所有问题的根源,在将它们设置为 all 之后NULL
,它现在运行良好。
ssh - 可能的 SSH PAM PTY 分配问题
我有一个托管在 Amazon EC2 上的 linux ubuntu 服务器。在系统上创建了大约 3000 多个 linux 用户,用户 ID 为 user_1、user_2 等。
令人惊讶的是,直到 user_2685 的用户都能够通过 ssh 登录到服务器。不止于此。
我已将 /etc/ssh/sshd_config 中的 LogLevel 更改为 DEBUG3。粘贴相关内容。
- 用户无法登录时的相关转储 - http://pastebin.com/NS2jC8vg
- 用户成功登录时的相关转储 - http://pastebin.com/vUXnpDsr
更新1:
以上转储来自服务器上的 /var/log/auth.log。以下是客户端上的转储。只需放置不同的转储的相关部分
登录成功
登录失败
操作系统:Ubuntu 精确 12.04
Openssh 服务器:OpenSSH_5.9p1 Debian-5ubuntu1.1, OpenSSL 1.0.1 14 Mar 2012
SSH 客户端:没关系,因为我在 ubuntu 和 Mac 上都试过,而且行为是一样的。
更新 2:
顺便说一句 - 这不是 PAM 的问题,就像我可以做su user_3000
的那样,新用户登录并获得 PTY。
同样在不要求 PTYssh -T user_3000@www.codelearn.org
的情况下执行 ssh 会登录用户。但它会停止登录后并且没有出现提示。可能那是因为一开始没有要求提示。
ruby - 未找到 PTY 宝石
我在 Windows 上安装了 Ruby 1.9.3。当我尝试要求 gem 时,控制台输出找不到 gem:
哪个输出:
我也试过:
并得到了这个输出:
我该如何解决?
unix - 为什么 OpenSSH RequestTTY 会导致 stderr 重定向到 stdout?
当使用 -T 和 -t 运行相同的 ssh 命令时,任何 stderr 输出分别到达 stderr 和 stdout。
未分配 pty:
ssh -T user@host "echo >&2 foo" 1>/tmp/out 2>/tmp/err
输出写入/tmp/err
.
使用 pty 分配:ssh -t user@host "echo >&2 foo" 1>/tmp/out 2>/tmp/err
输出现在写入/tmp/out
.
我有点理解,使用 pty 模拟了一个完整的伪屏幕,并且输出处于原始模式。发送到屏幕的输出然后通过 stdout 发送回 ssh,并且 ssh 的 tty 也设置为原始模式。有人可以进一步解释吗?
python - 扭曲矩阵中的错误:Windows 不支持 usePTY 参数
我正在尝试运行 PTY 服务器的扭曲文档中的示例代码示例,该服务器在连接时生成 shell。
此代码给出错误“Windows 不支持 usePTY 参数”。我希望有一种解决方法或任何可能有助于在 Windows 上运行它的方法。
python - python 2.7 - 与 mpg123 的子进程控制交互
几周前我在这里问了一个与此相关的问题: Python, mpg123 and subprocess not proper using stdin.write or communication
感谢那里的帮助,我能够做我当时需要的事情。(没有调用 q,但终止了子进程以停止它)。## Heading ## 现在虽然我似乎又有点乱了。
就像以前一样,我需要这个能够退出 mpg123,就像它的标准控件一样(比如按“q”退出,或“-”降低音量,“+”提高音量等),现在我使用上面的代码,理论上应该可以工作,并且可以与类似的程序一起工作。有谁知道我可以使用子进程使用 mpg123 内置的控件(通过使用“mpg123 -C 不管.mp3”访问的控件)的一种方式?终止已经不够了,因为我需要控件^_^
编辑:非常感谢 abarnert 的惊人答案 =) 好的,所以新代码只是 abarnert 答案的略微修改版本,但是 mpg123 似乎不接受命令
linux - forkpty 对被监禁的 linux 用户失败
我在服务器上安装了 Ubuntu 12.04。每个注册用户也被注册为 linux 用户并通过 /etc/security/limits.conf 被限制系统资源访问。
我尝试以注册用户之一的身份运行服务器。该应用程序是一个 nodejs 应用程序 - http://github.com/pocha/terminal-codelearn。它使用https://github.com/chjj/pty.js为来到 nodejs 应用程序的每个用户创建一个伪终端。
该应用程序失败,“forkpty(3) failed”错误指向https://github.com/chjj/pty.js/blob/65dd89fd8f87de914ff1814362918d7bd87c9cbf/src/unix/pty.cc的第 184 行
我能够在http://nitrous.io上成功部署该应用程序。他们可能与监狱用户有类似的方式。我尝试运行ulimits -a
并匹配除挂起信号之外的每个值。不知何故,在我的服务器上,最大挂起信号值不超过 90k 左右,而在 Nitrous 服务器上为 584k。
下面是 Nitrous 服务器的 ulimit -a 输出
该应用程序在 heroku 上失败,并出现完全相同的错误。
任何人都可以帮助如何使应用程序在我的服务器上运行,就像它在 nitrous.io 上的工作方式一样
c - forkpty + libreadline:自动完成问题
我在 C 和 Linux 中有一个小型 TCP 客户端/服务器应用程序,其中客户端可以通过 telnet 连接到服务器端 cli。在服务器上,调用accept 后,执行forkpty(3) 并转发master (pty) 和socket 之间的流量。从站 (pty) 实现了一个使用 libreadline 的 cli。这一切都已经很好了。
我唯一的问题是,如何让 libreadline 自动完成工作?我已经实现了自动完成,可以在我的 shell 上独立使用它,但不能在 pty 上使用(只是打印了两个选项卡)。任何提示都会很好!
python - 检测子进程何时等待输入
我正在编写一个 Python 程序,用于在 Linux 服务器上运行用户上传的任意(因此,在最坏的情况下,不安全、错误和崩溃)代码。除了安全问题之外,我的目标是确定代码(可能是任何语言,编译或解释)是否将正确的stdout
内容stderr
写入stdin
. 在此之后,我需要向用户显示结果。
目前的解决方案
目前,我的解决方案是subprocess.Popen(...)
使用stdout
,stderr
和stdin
. 句柄后面的文件stdin
包含程序在运行期间读取的输入,在程序终止后,将读取stdout
和stderr
文件并检查其正确性。
问题
这种方法在其他方面效果很好,但是当我显示结果时,我无法组合给定的输入和输出,以便输入出现在与从终端运行程序时相同的位置。即对于像这样的程序
包含程序的文件的内容stdout
在运行后将是:
鉴于包含 的文件的内容stdin
是Anonymous<LF>
. 因此,简而言之,对于给定的示例代码(以及等效地,对于任何其他代码),我希望获得如下结果:
因此,问题在于检测程序何时等待输入。
尝试过的方法
我尝试了以下方法来解决问题:
Popen.communicate(...)
这允许父进程沿管道单独发送数据,但只能调用一次,因此不适合具有多个输出和输入的程序 - 正如可以从文档中推断的那样。
直接从Popen.stdout和Popen.stderr读取并写入Popen.stdin
文档对此提出警告,当程序开始等待输入时,Popen.stdout
s.read()
和调用似乎无限阻塞。.readline()
用于select.select(...)
查看文件句柄是否已准备好进行 I/O
这似乎没有任何改善。显然管道总是准备好读取或写入,所以select.select(...)
在这里没有多大帮助。
使用不同的线程进行非阻塞读取
正如这个答案中所建议的,我尝试创建一个单独的Thread()来存储从读取stdout
到Queue()的结果。要求用户输入的行之前的输出行显示得很好,但程序开始等待用户输入的行("Type your name: "
在上面的示例中)永远不会被读取。
使用PTY slave 作为子进程的文件句柄
按照这里的指示,我尝试pty.openpty()
创建一个带有主从文件描述符的伪终端。之后,我给出了从属文件描述符作为subprocess.Popen(...)
调用的参数stdout
,stderr
和stdin
参数。读取打开的主文件描述符os.fdopen(...)
会产生与使用不同线程相同的结果:要求输入的行不会被读取。
编辑:使用@Antti Haapala 的pty.fork()
子进程创建示例而不是subprocess.Popen(...)
似乎允许我也阅读由raw_input(...)
.
使用pexpect
我还尝试了使用 pexpect 生成的进程的read()
,read_nonblocking()
和readline()
方法(在此处read_nonblocking()
记录),但是我得到的最佳结果与以前相同:在希望用户输入之前带有输出的行没有阅读。与使用创建的 PTY 相同:确实会读取pty.fork()
要求输入的行。
编辑:通过在我的创建子程序的主程序中使用sys.stdout.write(...)
andsys.stdout.flush()
而不是print
ing ,似乎修复了提示行未显示的问题——尽管它实际上在两种情况下都被读取了。
其他
我也试过select.poll(...)
,但似乎管道或 PTY 主文件描述符总是准备好写入。
笔记
其他解决方案
- 我还想到的是在一段时间过去而没有生成新输出的情况下尝试输入输入。然而,这是有风险的,因为无法知道程序是否正在执行繁重的计算。
- 正如@Antti Haapala 在他的回答中提到的那样,
read()
可以替换来自 glibc 的系统调用包装器以将输入传达给主程序。但是,这不适用于静态链接或汇编程序。(虽然,现在我想起来了,任何这样的调用都可以从源代码中截获并替换为read()
- 的修补版本可能仍然很难实现。) - 修改 Linux 内核代码以将
read()
系统调用传达给程序可能是疯狂的......
PTY
我认为 PTY 是要走的路,因为它伪造了一个终端,并且交互式程序在任何地方的终端上运行。问题是,怎么做?
linux - 在不关闭 pty 的情况下指示不再输入
在使用 PTY 主/从对控制进程时,我想向相关进程表明标准输入已关闭并且我没有更多内容要发送,但我仍想接收来自该进程的输出。
问题是我只有一个文件描述符(PTY“主”),它处理来自子进程的输入和输出到子进程。所以关闭描述符会关闭两者。
python中的示例: