为了账号安全,请及时绑定邮箱和手机立即绑定

从 Go 程序内部调用源

从 Go 程序内部调用源

Go
慕沐林林 2021-10-11 13:35:38
为了好玩和更好地学习围棋,我正在尝试在围棋中重新实现抗原。问题是:source是一个 shell 内置函数,所以我不能用os/exec Command函数调用它,因为它需要一个PATH.我怎样才能做到这一点?并且,是否可以source从 go 程序内部进行影响用户 shell?
查看完整描述

1 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

您可以直接在终端设备中编写命令。但是,要做到这一点,首先您需要知道用户正在使用哪个设备。执行程序的脚本可以是一种解决方案。


#!/bin/bash

echo Running from foo script, pid = $$

go run foo.go `tty`

然后,程序必须将命令写入终端设备。


package main


import (

    "C"

    "fmt"

    "os"

    "syscall"

    "unsafe"

)


func main() {

    // Get tty path

    if len(os.Args) < 2 {

        fmt.Printf("no tty path\n")

        os.Exit(1)

    }

    ttyPath := os.Args[1]


    // Open tty

    tty, err := os.Open(ttyPath)

    if err != nil {

        fmt.Printf("error opening tty: %s\n", err.Error())

        os.Exit(2)

    }

    defer tty.Close()


    // Write a command

    cmd := "echo Hello from go, pid = $$\n"

    cmdstr := C.CString(cmd)

    cmdaddr := uintptr(unsafe.Pointer(cmdstr))

    for i := range []byte(cmd) {

        _, _, err := syscall.Syscall(syscall.SYS_IOCTL, tty.Fd(), syscall.TIOCSTI, cmdaddr+uintptr(i))

        if uintptr(err) != 0 {

            fmt.Printf("syscall error: %s\n", err.Error())

            os.Exit(3)

        }

    }

}

这是一个示例输出:


$ echo $$

70318

$ ./foo 

Running from foo script, pid = 83035

echo Hello from go, pid = $$

$ echo Hello from go, pid = $$

Hello from go, pid = 70318

请注意,我正在使用./not执行脚本source,因此脚本的 PID 不同。但是后来,go程序执行的命令有相同的PID。


查看完整回答
反对 回复 2021-10-11
  • 1 回答
  • 0 关注
  • 179 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信