我正在编写一些带有文件的代码,将该文件传递给多个二进制文件之一进行处理,并监视转换过程中的错误.我已经在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-
我正在Rust中创建一个小的ncurses应用程序,需要与子进程通信.我已经有了一个用Common Lisp编写的原型; 这里的gif 将有希望展示我想做的事情.我正在尝试重写它,因为CL为这么小的工具使用了大量的内存.
我之前没有使用过Rust(或其他低级语言),而且我在弄清楚如何与子进程交互时遇到了一些麻烦.
我目前正在做的大致是这样的:
创建流程:
let mut program = match Command::new(command)
.args(arguments)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
{
Ok(child) => child,
Err(_) => {
println!("Cannot run program '{}'.", command);
return;
}
};
Run Code Online (Sandbox Code Playgroud)将它传递给无限(直到用户退出)循环,该循环读取并处理输入并像这样监听输出(并将其写入屏幕):
fn listen_for_output(program: &mut Child, output_viewer: &TextViewer) {
match program.stdout {
Some(ref mut out) => {
let mut buf_string = String::new();
match out.read_to_string(&mut buf_string) {
Ok(_) => output_viewer.append_string(buf_string),
Err(_) => return,
};
}
None => return,
};
}
Run Code Online (Sandbox Code Playgroud)read_to_string然而,调用阻止程序直到进程退出.从我所看到的read_to_end,read似乎也阻止.如果我尝试运行类似于ls哪个退出的东西,它可以工作,但是有些东西不能退出, …
我正在试图弄清楚如何在linux中使用伪终端,基本上我想创建一个telnetd克隆,我之前在一个问题中提到过.
我理解主从终端的概念,我对如何在C中使用系统调用有了基本的把握.
我的问题涉及打开slave/master文件描述符后的下一步.如何在奴隶中推出getty?网上是否有使用forkpty(),openpty()或其他API的好资源?
C中的一些例子会有所帮助.这是一个非常相似的问题,但没有人真正提供任何例子.
我正在从一个项目进行npm安装,我在node-gyp中遇到了这个奇怪的错误.
> pty.js@0.2.3 install /home/charizard/Open/terminal-codelearn/node_modules/pty.js
> node-gyp rebuild
npm http GET https://registry.npmjs.org/commander
npm http GET https://registry.npmjs.org/nan
npm http GET https://registry.npmjs.org/tinycolor
npm http GET https://registry.npmjs.org/options
gyp ERR! configure error
gyp ERR! stack Error: "pre" versions of node cannot be installed, use the --nodedir flag instead
gyp ERR! stack at install (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/install.js:65:16)
gyp ERR! stack at Object.self.commands.(anonymous function) [as install] (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/node-gyp.js:66:37)
gyp ERR! stack at getNodeDir (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:228:20)
gyp ERR! stack at /usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:110:9
gyp ERR! stack at ChildProcess.exithandler (child_process.js:659:7)
gyp ERR! stack at …Run Code Online (Sandbox Code Playgroud) 我正在使用NSTask和NSTextView编写一个简单的终端.如何和应该实施?openptyCtrlCCtrlD
我开始像这样的shell:
int amaster = 0, aslave = 0;
if (openpty(&amaster, &aslave, NULL, NULL, NULL) == -1) {
NSLog(@"openpty failed");
return;
}
masterHandle = [[NSFileHandle alloc] initWithFileDescriptor:amaster closeOnDealloc:YES];
NSFileHandle *slaveHandle = [[NSFileHandle alloc] initWithFileDescriptor:aslave closeOnDealloc:YES];
NSTask *task = [NSTask new];
task.launchPath = @"/bin/bash";
task.arguments = @[@"-i", @"-l"];
task.standardInput = slaveHandle;
task.standardOutput = slaveHandle;
task.standardError = errorOutputPipe = [NSPipe pipe];
[task launch];
Run Code Online (Sandbox Code Playgroud)
然后我拦截CtrlC并发-[interrupt]送到NSTask这样的:
- (void)keyDown:(NSEvent …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个将在服务器上远程执行的执行环境/ shell,它将stdout,err,流入套接字以在浏览器中呈现.我目前已经尝试过使用subprocess.runa 的方法PIPE.问题是我在进程完成后得到了stdout.我想要实现的是获得逐行,伪终端类型的实现.
我目前的实施
test.py
def greeter():
for _ in range(10):
print('hello world')
greeter()
Run Code Online (Sandbox Code Playgroud)
并在壳中
>>> import subprocess
>>> result = subprocess.run(['python3', 'test.py'], stdout=subprocess.PIPE)
>>> print(result.stdout.decode('utf-8'))
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
Run Code Online (Sandbox Code Playgroud)
如果我尝试尝试这个简单的实现pty,如何做到这一点?
我有一个在伪终端中运行的子进程.父进程不以root身份运行,但子进程通过su或sudo运行.因此,无法向子进程发送信号以强制它退出.我想通过以下方法之一强制退出:
我该怎么做?我已经有一个pty master fd,我尝试过这样的事情:
write(master, &termios.c_cc[VINTR], 1)
Run Code Online (Sandbox Code Playgroud)
但它没有做任何事情.
从串行设备(/ dev/ttyXX)读取多个进程使得两个进程都无法获取所有数据 - 数据将以某种方式在它们之间进行分割.我想编写一个从串行设备读取的程序,创建几个主/从pty对,然后允许从串行设备读取的程序从ptys读取,以便所有读取进程接收数据从串行设备开始,让ptys就像串行设备一样,当他们从pty开始读取时,他们只得到最新的数据.换句话说,在开始阅读之前你不会得到任何数据(这是我的经验,这就是/ dev/ttyXX设备的工作方式,或者至少是我正在阅读的RS-232风速计).命名管道可以通过捕获SIGPIPE来模仿这些语义,以确定没有读取器,因此我们可以选择不写入该特定命名管道.但是,在与命名管道通信时,写入使用终端的某些二进制文件可能会失败,因为对isatty()的检查和对tcsetattr()等调用的错误条件可能会导致失败的情况.这里的关键是能够使用为终端编写的现有二进制文件.
因此,如果我能够检测到pty的slave端何时被打开以进行读取,那么这应该给出与命名管道情况中没有SIGPIPE大致相同的语义.我注意到HP-UX将TIOCTRAP作为ioctl()命令,它似乎完全符合我的要求,但遗憾的是它在Linux上不可用.
我已经阅读了几天的参考文献,这种类型的东西的选项数量是惊人的.答案可能在于终端设置,阻塞/非阻塞行为,在某处设置缓冲区大小,从poll()/ select()报告的条件,或某些组合.但我似乎找不到任何东西.我想知道是否有可能我需要编写自己的设备驱动程序,但似乎我应该能够做到这一点而不用那么远.
所以,为了澄清:
- 问题是:如何检测有人在Linux中打开pty(伪终端)的从属端?
- 我希望读者打开pty的slave端接收读取器打开pty后严格写入的数据(如果我的多次写入过程只是在读取器打开从属端之前写入数据一段时间,数据将缓冲并且最终编写器将阻塞,并且从属读取器在打开时将立即获得所有缓冲数据 - 这是不可取的,因为我希望它只获得在紧邻时间附近生成的数据)
- 它必须是一个pty,而不是命名管道,套接字等,因为isatty()和tcsetattr()等需要正常,以便现有的二进制文件工作
嗨,根据这篇文章,unbuffer通过伪终端(pty)连接到命令,这使得系统将其视为交互式进程,因此不使用任何stdout缓冲.
我想在Windows上使用此功能.我可以知道unbufferWindows 上程序的等价物吗?谢谢.
我一直在阅读这个页面的例子中的ptys:http://rachid.koucha.free.fr/tech_corner/pty_pdip.html.我有两个问题:
使用pty和使用管道有什么区别或最重要的区别?从我所读到的,两者都是用于进程间通信,但是通过pty,进程可以"像对待普通终端一样对待它".那是什么意思?
什么是"控制终端"?我读过他们但却无法理解他们到底是什么.控制终端总是分配给流程的pty吗?