Go语言:无法更改子进程的标准输入(stdin)。

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

Go Lang: Can't change children's stdin

问题

我想完全在父进程和子进程中禁用STDIN

上下文:
我从主Go进程中生成子进程。它在Go协程中生成。不知何故,文件描述符(在这种情况下是stdin)被子进程继承。我的目标是将子进程的stdin设置为nil,以禁止任何stdin输入到子进程中。

我尝试过:

os.Stdin = nil

os.Stdin = os.NewFile(uintptr(syscall.Stdin), "/dev/null")

我找到的唯一“解决方案”是比较糟糕的:

func init() {
	go func() {
		for {
			io.Copy(os.Stdout, os.Stdin)
		}
	}()
}

有人知道更好的解决方案吗?

更新:
如果Go程序从/dev/tty读取,os.Stdin = nil 将不起作用。

我正在生成FFUF

go func() {
	tty, err := os.Open("/dev/tty")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer tty.Close()

	inreader := bufio.NewScanner(tty)
	inreader.Split(bufio.ScanLines)

	started <- true
	for inreader.Scan() {
		fmt.Printf("handle: " + inreader.Text())
	}
}()
英文:

I want to completelly drop STDIN in parent and children processes.

CONTEXT:<br>
I am spawning children process from main Go process. It is spawned in Go routine. Somehow FDs (stdin in this case) are inherited by children process. My goal is to set stdin of children process to nil, in order to forbid any stdin to the children process.

I tried:

os.Stdin = nil

os.Stdin = os.NewFile(uintptr(syscall.Stdin), &quot;/dev/null&quot;)

Only "solution" which I found is dirty:

func init() {
	go func() {
		for {
			io.Copy(os.Stdout, os.Stdin)
		}
	}()
}

Does anybody know better solution?

UPDATE:<br>
os.Stdin = nil won't work if Go program is reading from /dev/tty

I am spawning FFUF

go func() {
	tty, err := os.Open(&quot;/dev/tty&quot;)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer tty.Close()

	inreader := bufio.NewScanner(tty)
	inreader.Split(bufio.ScanLines)

	started &lt;- true
	for inreader.Scan() {
		fmt.Printf(&quot;handle: &quot; + inreader.Text())
	}
}()

答案1

得分: 1

我找到了一个解决方案。你需要创建一个没有TTY的进程。为了做到这一点,需要使用syscall的SysProcAttr函数,并设置Setsid和Setctty参数。

cmd := exec.Command("echo")

cmd.SysProcAttr = &syscall.SysProcAttr{
    Setsid:  true,
    Setctty: false,
}

cmd.Start()

cmd.Write([]byte("hello grep\ngoodbye grep"))
cmd.Close()

cmd.Wait()

希望对你有帮助!

英文:

I found a solution. You need to spawn a process without TTY.
To do it, it is necessary to perform syscall SysProcAttr with Setsid and Setctty parameters.

cmd := exec.Command(&quot;echo&quot;)

cmd.SysProcAttr = &amp;syscall.SysProcAttr{
	Setsid:  true,
	Setctty: false,
}

cmd.Start()

cmd.Write([]byte(&quot;hello grep\ngoodbye grep&quot;))
cmd.Close()

cmd.Wait()

huangapple
  • 本文由 发表于 2022年11月10日 22:46:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/74390889.html
匿名

发表评论

匿名网友

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

确定