以编程方式为 os.Process 编写 stdin。

huangapple go评论65阅读模式
英文:

Programmatically writing stdin for an os.Process

问题

更新:要以编程方式“驱动”bash,您需要一个伪终端(PTY)。这就是我正在寻找的:

https://github.com/kr/pty

package main

import (
    "github.com/kr/pty"
    "io"
    "os"
    "os/exec"
)

func main() {
    c := exec.Command("grep", "--color=auto", "bar")
    f, err := pty.Start(c)
    if err != nil {
        panic(err)
    }

    go func() {
        f.Write([]byte("foo\n"))
        f.Write([]byte("bar\n"))
        f.Write([]byte("baz\n"))
        f.Write([]byte{4}) // EOT
    }()
    io.Copy(os.Stdout, f)
}

给定以下示例:

package main

import (
	"fmt"
	"os"
)

func main() {
	attr := &os.ProcAttr{
		Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
	}
	process, err := os.StartProcess("/bin/bash", nil, attr)
	if err != nil {
		fmt.Printf("process err %v\n", err)
		return
	}
	state, err := process.Wait()
	if err != nil {
		fmt.Printf("wait err %v\n", err)
	}
	fmt.Printf("'%+v'\n", state)
}

我可以按预期运行bash

go run proc.go
bash-3.2$ echo foo
foo
bash-3.2$ exit
exit
'exit status 0'

然而,我想为os.Stdin指定自己的可写流,当我尝试传递一个文件(os.Open("/my/file"))时,进程将文件作为stdin并在io.EOF处退出。如何创建一个“无限长”的可写文件?通过查看文档,似乎我需要以某种方式使用os.OpenFile...

英文:

Update: To programmatically "drive" bash, you need a Pseudo terminal (PTY).This is what I looking for:

https://github.com/kr/pty

package main

import (
    "github.com/kr/pty"
    "io"
    "os"
    "os/exec"
)

func main() {
    c := exec.Command("grep", "--color=auto", "bar")
    f, err := pty.Start(c)
    if err != nil {
        panic(err)
    }

    go func() {
        f.Write([]byte("foo\n"))
        f.Write([]byte("bar\n"))
        f.Write([]byte("baz\n"))
        f.Write([]byte{4}) // EOT
    }()
    io.Copy(os.Stdout, f)
}

Given the following example:

package main

import (
	"fmt"
	"os"
)

func main() {
	attr := &os.ProcAttr{
		Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
	}
	process, err := os.StartProcess("/bin/bash", nil, attr)
	if err != nil {
		fmt.Printf("process err %v\n", err)
		return
	}
	state, err := process.Wait()
	if err != nil {
		fmt.Printf("wait err %v\n", err)
	}
	fmt.Printf("'%+v'\n", state)
}

I can run bash as expected:

go run proc.go
bash-3.2$ echo foo
foo
bash-3.2$ exit
exit
'exit status 0'

However, I'd like to specify my own writable stream for os.Stdin and when I try passing it a file (os.Open("/my/file")), the process takes the file as stdin and exits at io.EOF. How can I create an "infinitely long" writable file?

Looking through the docs it seems I'd need to use os.OpenFile in some way...

答案1

得分: 2

你无法这样做。但是,你可以创建一个 os.Pipe() 并将文件推送到其中一侧。只要不关闭管道,它就会无限进行下去。

英文:

You can't. However, you can create an os.Pipe() and push your file to one side. It will be inifinite as long as you do not close the pipe.

huangapple
  • 本文由 发表于 2014年10月19日 11:02:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/26446868.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定