标签: pty

如何为我在pty下运行的进程设置终端前台进程组?

我写了一个简单的包装脚本,用于在失败时重复命令retry.py.但是,由于我想看到子命令的输出,我不得不拉一些pty技巧.这适用于像rsync这样的程序,但是像scp这样的其他程序会应用额外的测试来显示像进度表这样的东西.

scp代码有一个广泛的测试:

getpgrp() == tcgetpgrp(STDOUT_FILENO);
Run Code Online (Sandbox Code Playgroud)

当我运行包装器脚本时,这会失败.正如您在我的简单tty_test.c测试用例中看到的:

./tty_tests
isatty reports 1
pgrps are 13619 and 13619
Run Code Online (Sandbox Code Playgroud)

和:

./retry.py -v -- ./tty_tests
command is ['./tty_tests']
isatty reports 1
pgrps are 13614 and -1
child finished: rc = 0
Ran command 1 times
Run Code Online (Sandbox Code Playgroud)

我已经尝试使用tcsetpgrp(),最终作为pty fd的IOCTL,但这导致了ptys的-EINVAL.如果可能的话,我宁愿继续使用Python子进程机器,还是需要手动fork/execve'ing?

python posix subprocess pty posix-api

6
推荐指数
1
解决办法
1157
查看次数

当pty [伪终端]从属fd设置被"tcsetattr"改变时,主端如何无延迟地捕获此事件?

slave fd被另一个应用程序(比如"A")用作串行端口设备.

A将设置其波特率/停止位等.我的应用程序需要此信息.

顺便说一下,有没有办法让只有主fd打开的进程被通知所有ioctl()发给奴隶fd的电话?

linux ioctl pty

6
推荐指数
1
解决办法
877
查看次数

Python pty.spawn stdin没有回显但重定向到master的stdout

我想从Python调用一个程序,并让它相信stdout即使Python的进程stdout附加到管道上它也是一个tty.所以我使用该pty.spawn函数来实现这一点,可以从以下方面进行验证:

$ python -c "import sys; from subprocess import call; call(sys.argv[1:])" python -c "import sys; print sys.stdout.isatty()" | cat
False

$ python -c "import sys; import pty; pty.spawn(sys.argv[1:])" python -c "import sys; print sys.stdout.isatty()" | cat
True
Run Code Online (Sandbox Code Playgroud)

(我们看到在第二个命令中我们已经实现了我们的目标,即生成的进程被欺骗认为它的标准输出是tty.)

但问题是如果我们使用pty.spawn那么它的输入不会被回显,而是被重定向到主的标准输出.这可以通过以下命令看到:

$ python -c "import sys; import pty; pty.spawn(sys.argv[1:])" cat > out.txt
$ # Typed "hello" in input, but that is not echoed (use ^D to exit). It is redirected to output.txt
$ cat out.txt
hello …
Run Code Online (Sandbox Code Playgroud)

python linux bash stdin pty

6
推荐指数
1
解决办法
1277
查看次数

forkpty - 插座

我正在尝试开发一个简单的“telnet/server”守护进程,它必须在新的套接字连接上运行一个程序。这部分工作正常。

但是我必须将我的新进程与 pty 相关联,因为该进程具有一些终端功能(如 readline)。

我开发的代码是(其中 socketfd 是新输入连接的新套接字文件描述符):

int masterfd, pid;
const char *prgName = "...";
char *arguments[10] = ....;

if ((pid = forkpty(&masterfd, NULL, NULL, NULL)) < 0)
    perror("FORK");
else if (pid)
    return pid;
else
{
    close(STDOUT_FILENO);
    dup2(socketfd, STDOUT_FILENO);

    close(STDIN_FILENO);
    dup2(socketfd, STDIN_FILENO);

    close(STDERR_FILENO);
    dup2(socketfd, STDERR_FILENO);

    if (execvp(prgName, arguments) < 0)
    {
        perror("execvp");
        exit(2);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用该代码,我的“prgName”的 stdin / stdout / stderr 文件描述符与套接字相关联(使用 ls -la /proc/PID/fd 查看时),因此,此进程的终端功能不起作用.

通过远程设备上的 ssh/sshd 连接进行测试,并执行“localy”(在 ssh 连接下)prgName,表明此进程“prgName”的 stdin/stdout/stderr fd 与 pty(等等)相关联此过程的终端功能运行良好)。

我做错了什么?如何将我的 socketfd 与 pty(由 …

c sockets linux pty

5
推荐指数
1
解决办法
4602
查看次数

有没有像 Python 的 Ruby 的 pty.fork 之类的东西?

我正在尝试将如下所示的 Python 代码移植到 Ruby:

import pty

pid, fd = pty.fork
if pid == 0:
  # figure out what to launch
  cmd = get_command_based_on_user_input()

  # now replace the forked process with the command
  os.exec(cmd)
else:
  # read and write to fd like a terminal
Run Code Online (Sandbox Code Playgroud)

由于我需要像终端一样读取和写入子进程,我明白我应该使用 Ruby 的 PTY 模块来代替 Kernel.fork。但它似乎没有等效的 fork 方法;我必须将命令作为字符串传递。这是我能得到的最接近 Python 功能的方法:

require 'pty'

# The Ruby executable, ready to execute some codes
RUBY = %Q|/proc/#{Process.id}/exe -e "%s"|

# A small Ruby program which will eventually replace itself with …
Run Code Online (Sandbox Code Playgroud)

ruby python linux fork pty

5
推荐指数
1
解决办法
530
查看次数

未找到 PTY 宝石

我在 Windows 上安装了 Ruby 1.9.3。当我尝试要求 gem 时,控制台输出找不到 gem:

require 'pty'
Run Code Online (Sandbox Code Playgroud)

哪个输出:

'require': cannot load such file -- pty <LoadError>
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

gem install pty
Run Code Online (Sandbox Code Playgroud)

并得到这个输出:

Could not find a valid gem 'pty' in any repository
Run Code Online (Sandbox Code Playgroud)

我该如何解决?

ruby gem pty

5
推荐指数
1
解决办法
2880
查看次数

连接到 stdout 和 stderr 的单独 pty 的进程

我正在编写一个终端日志程序- 想想这个script命令,但功能更强大。区别之一是,虽然script将 stdout、stdin 和 stderr 捕获为一个大字符流,但我希望将它们分开并按原样记录。

为了做到这一点,我使用了运行连接到 pty 的子 shell 的标准方法,但我使用了两个 pty——stdin 和 stderr 连接到了两个 pty,而不是使用一个带有 stdin、stdout 和 stderr 的单个 pty。一个 pty,另一个是标准输出。这样,主进程就可以分辨出什么来自 stdout,什么来自 stderr。

到目前为止,这运行良好。但是,我开始遇到一些问题。例如,当尝试设置列数时,我得到以下信息:

$stty cols 169

stty:stdout 出现重定向,但 stdin 是控制描述符

这似乎是这段代码的结果,它似乎检查 stdout 和 stderr 是否都是 ttys,但如果它们不一样就会抱怨。

因此,我的问题是:我是否违反了关于 Posix 进程如何以这种方式行事的任何基本假设?如果没有,知道为什么我会看到这样的错误吗?如果是这样,有什么办法可以解决这个问题,并且仍然设法很好地分离 stdout 和 stderr?

linux posix pty

5
推荐指数
1
解决办法
1143
查看次数

在 NodeJS 进程中创建一个 bash 包装器

我想构建一个正在运行的小脚本,它应该创建一个类似 bash 的会话(在当前的 bash 会话中,创建进程的地方),稍后可以用于一些疯狂的科学(例如管道到浏览器)。

我尝试使用pty.js,管道stdinbash进程,以及从 bash 会话到stdout流的数据:

var pty = require("pty.js");

var term = pty.spawn('bash', [], {
  name: 'xterm-color',
  cols: process.stdout.columns,
  rows: process.stdout.rows,
  cwd: ".",
  env: process.env
});

term.pipe(process.stdout);
process.stdin.pipe(term);

term.on("close", function () {
    process.exit();
});
Run Code Online (Sandbox Code Playgroud)

这有效,但它非常有问题:

例如,不会捕获非字符(方向键、制表符等)。

我也尝试使用spawn,这还不错,但仍然有问题。

var spawn = require("child_process").spawn;

var bash = spawn("bash");
bash.stdout.pipe(process.stdout);
process.stdin.pipe(bash.stdin);
Run Code Online (Sandbox Code Playgroud)

有没有更好的解决方案如何在 NodeJS 中创建 bash 包装器?

linux bash shell pty node.js

5
推荐指数
1
解决办法
796
查看次数

如何检测分配的终端设备进行交互式工作

我正在写寻呼机pspg.我必须解决以下问题.读完之后,stdin我应该stdin从之前的阅读管道重新分配到终端阅读.

我用了

freopen("/dev/tty", "r", stdin) 
Run Code Online (Sandbox Code Playgroud)

但是,当从命令中使用寻呼机时,它不起作用

su - someuser -c 'export PAGER=pspg psql somedb'
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我收到一个错误:没有这样的设备或地址.

我找到了一个解决方法 - 现在,代码看起来像:

if (freopen("/dev/tty", "r", stdin) == NULL)
{
    /*
     * try to reopen pty.
     * Workaround from:
     * https://cboard.cprogramming.com/c-programming/172533-how-read-pipe-while-keeping-interactive-keyboard-c.html
     */
    if (freopen(ttyname(fileno(stdout)), "r", stdin) == NULL)
    {
        fprintf(stderr, "cannot to reopen stdin: %s\n", strerror(errno));
        exit(1);
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,检测分配的终端设备的正确方法是什么?

但这种解决方法不正确.它解决了一个问题,但接下来就要来了.当某个用户与当前用户不同时,重新打开失败,并显示" 权限被拒绝"错误.因此,此解决方法不能用于我的目的.

c unix tty pty

5
推荐指数
1
解决办法
192
查看次数

你如何写信给 Pty 大师 Rust

我创建了一个简单的 pty 设置,但是我不确定如何在创建后实际写入主端或从端。我也不确定我的设置是否正确,因为经过检查,pty 的子进程的 Stdin、Stdout 和 Stderr 都是 None 而不是设置为从文件描述符。任何人都可以澄清这是否正确,如果不正确,您对如何解决它有任何建议吗?

use libc::{self};
use nix::pty::openpty;
use std::os::unix::io::FromRawFd;
use std::process::{Child, Command, Stdio};

#[derive(Debug)]
pub struct Pty {
    process: Child,
    fd: i32,
}

fn create_pty(process: &str) -> Pty {
    let ends = openpty(None, None).expect("openpty failed");
    let master = ends.master;
    let slave = ends.slave;

    let mut builder = Command::new(process);
    builder.stdin(unsafe { Stdio::from_raw_fd(slave) });
    builder.stdout(unsafe { Stdio::from_raw_fd(slave) });
    builder.stderr(unsafe { Stdio::from_raw_fd(slave) });

    match builder.spawn() {
        Ok(process) => {
            let pty = Pty {
                process,
                fd: …
Run Code Online (Sandbox Code Playgroud)

unix libc tty pty rust

5
推荐指数
1
解决办法
479
查看次数

标签 统计

pty ×10

linux ×6

python ×3

bash ×2

c ×2

posix ×2

ruby ×2

tty ×2

unix ×2

fork ×1

gem ×1

ioctl ×1

libc ×1

node.js ×1

posix-api ×1

rust ×1

shell ×1

sockets ×1

stdin ×1

subprocess ×1