doucai9270 2016-09-06 15:04
浏览 67
已采纳

为什么此exec.Command到另一个打开的tty不能正常工作

Can anybody please help me figure out what I'm doing wrong here.

I'm trying to execute a command (opening vim in this case) that runs in a different tty, in this case /dev/ttys001, which is opened in another tab in my terminal.

Running the code below does render vim in /dev/ttys001's window, however, actually typing to stdin from that window doesn't register properly.

Any advice is much appreciated!

package main

import (
    "log"
    "os"
    "os/exec"
)

func main() {
    tty, err := os.OpenFile("/dev/ttys001", os.O_RDWR, os.ModePerm)
    if err != nil {
        log.Fatalln(err)
    }
    defer tty.Close()

    c := exec.Command("vim")
    c.Stdin = tty
    c.Stdout = tty
    c.Stderr = tty
    if err := c.Run(); err != nil {
        log.Fatalln(err)
    }
}

I have also tried setting the command's SysProcAttr field with the following code but receive the error: fork/exec /usr/local/bin/vim: inappropriate ioctl for device.

procAttr := &syscall.SysProcAttr{
    Setpgid:    true,
    Ctty:       int(tty.Fd()),
    Foreground: true,
}
c.SysProcAttr = procAttr
  • 写回答

1条回答 默认 最新

  • duan051347 2016-09-07 14:25
    关注

    For anybody who's interested, I came up with a solution, but I ended up having to use system calls instead of the os/exec package's functions.

    package main
    
    import (
        "log"
        "os"
        "syscall"
        "unsafe"
    )
    
    var tty = "/dev/ttys001"
    var cmd = "vim
    "
    
    func main() {
        ttyFile, err := os.Open(tty)
        if err != nil {
            log.Fatalln(err)
        }
        defer ttyFile.Close()
    
        cbs, err := syscall.ByteSliceFromString(cmd)
        if err != nil {
            log.Fatalln(err)
        }
    
        var eno syscall.Errno
        for _, c := range cbs {
            _, _, eno = syscall.Syscall(syscall.SYS_IOCTL,
                ttyFile.Fd(),
                syscall.TIOCSTI,
                uintptr(unsafe.Pointer(&c)),
            )
            if eno != 0 {
                log.Fatalln(eno)
            }
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序