gpt4 book ai didi

ubuntu - 作为外部进程启动时,Unix 脚本命令不捕获标准输入

转载 作者:行者123 更新时间:2023-12-04 18:34:47 25 4
gpt4 key购买 nike

我的情况类似于Redirect Stdin and Stdout to File .我想运行一个程序并捕获运行程序的整个 session (stdin 和 stdout),就好像它是从终端以交互方式运行的一样。

来自 Dump terminal session to file我发现 script命令会起作用。这是执行此操作的程序的简化版本(用 Groovy 编写)。

import groovy.io.GroovyPrintWriter

def OUTPUT_FILE = "output.txt"

def sysout = new StringBuffer()
def syserr = new StringBuffer()

// On Linux (Ubuntu 12.04) - starts the bc command with script and capture session to OUTPUT_FILE
Process proc = "script -q -f -c bc ${OUTPUT_FILE}".execute()
// On OS X with a slightly different version of Script
// Process proc = "script -q ${OUTPUT_FILE} bc".execute()

proc.consumeProcessOutput(sysout, syserr) // Spawns separate threads that will consume the out to prevent overflow

proc.withWriter { writer ->
// Writes the following commands to the spawned process
def gWriter = new GroovyPrintWriter(writer)
// Imagine that the user enters these lines
gWriter.println "a = 5"
gWriter.println "b = 4"
gWriter.println "c = a * b"
gWriter.println "c"
gWriter.println "quit"
}

proc.waitForOrKill(20000) // Give it 20 seconds to complete or kill the process

println 'Standard out captured from process:\n' + sysout
println 'Standard err captured from process:\n' + syserr

我编写的程序适用于 OS X 上可用的脚本版本。在 OS X 上,整个 session 被捕获在 sysout 变量中,并正确写入 OUTPUT_FILE。

这是我期望得到的
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. a = 5
b = 4
c = a * b
c
20
quit

但是, 这是我得到的在 Linux (Ubuntu 12.04) 上,它省略了输入到 STDIN 的所有内容,只捕获 STDOUT。这是 sysout 和 OUTPUT_FILE 的内容
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
20

如您所见,行 a = 4, b = 5, etc缺失。

当我运行 script在 Linux 上从命令行提示符( script -q -f -c bc output.txt} 手动输入命令并逐行输入,它可以工作,即所有行也写入 OUTPUT_FILE。

我需要做哪些额外的步骤才能让我的程序在 Linux 上运行?我知道该程序可以在 OS X 上运行,因此该程序(或 Groovy)不太可能出现问题。我怀疑它必须与 Linux 版本的脚本在作为外部进程启动时的行为方式有关。

任何指针将不胜感激。

最佳答案

我不确定为什么会在 Ubuntu 而不是 OS X 上发生这种情况,但是 Ubuntu 上的一种可能的解决方法可能是用您自己的类装饰编写器,该类将写入的字符附加到 StringBuffer。

它不是很漂亮,因为您必须添加特定于操作系统的代码以确保输出不会在 OS X 上包含两次。

无论如何,这是带有装饰器类的完整脚本,它在使用 Groovy 2.0.5 的 Ubuntu 12.04 上对我来说很好。

import groovy.io.GroovyPrintWriter

def OUTPUT_FILE = "output.txt"

def sysout = new StringBuffer()
def syserr = new StringBuffer()

// On Linux (Ubuntu 12.04) - starts the bc command with script and capture session to OUTPUT_FILE
Process proc = "script -q -f -c bc ${OUTPUT_FILE}".execute()
// On OS X with a slightly different version of Script
// Process proc = "script -q ${OUTPUT_FILE} bc".execute()

proc.consumeProcessOutput(sysout, syserr) // Spawns separate threads that will consume the out to prevent overflow

proc.withWriter { writer ->
// Writes the following commands to the spawned process
def gWriter = new GroovyPrintWriter(new MyCaptureWriter(writer, sysout))
// Imagine that the user enters these lines
gWriter.println "a = 5"
gWriter.println "b = 4"
gWriter.println "c = a * b"
gWriter.println "c"
gWriter.println "quit"
}

proc.waitForOrKill(20000) // Give it 20 seconds to complete or kill the process

println 'Standard out captured from process:\n' + sysout
println 'Standard err captured from process:\n' + syserr

class MyCaptureWriter extends Writer {

@Delegate OutputStreamWriter writer
def sysout

MyCaptureWriter(writer, sysout) {
this.writer = writer
this.sysout = sysout
}

@Override
void write(char[] cbuf, int off, int len) throws IOException {
sysout.append(cbuf, off, len)
writer.write(cbuf, off, len)
}
}

关于ubuntu - 作为外部进程启动时,Unix 脚本命令不捕获标准输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14554625/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com