猿问

从 Go 程序内部调用源

为了好玩和更好地学习围棋,我正在尝试在围棋中重新实现抗原。

问题是:source是一个 shell 内置函数,所以我不能用os/exec Command函数调用它,因为它需要一个PATH.

我怎样才能做到这一点?并且,是否可以source从 go 程序内部进行影响用户 shell?


慕沐林林
浏览 180回答 1
1回答

弑天下

您可以直接在终端设备中编写命令。但是,要做到这一点,首先您需要知道用户正在使用哪个设备。执行程序的脚本可以是一种解决方案。#!/bin/bashecho Running from foo script, pid = $$go run foo.go `tty`然后,程序必须将命令写入终端设备。package mainimport (&nbsp; &nbsp; "C"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "os"&nbsp; &nbsp; "syscall"&nbsp; &nbsp; "unsafe")func main() {&nbsp; &nbsp; // Get tty path&nbsp; &nbsp; if len(os.Args) < 2 {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("no tty path\n")&nbsp; &nbsp; &nbsp; &nbsp; os.Exit(1)&nbsp; &nbsp; }&nbsp; &nbsp; ttyPath := os.Args[1]&nbsp; &nbsp; // Open tty&nbsp; &nbsp; tty, err := os.Open(ttyPath)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("error opening tty: %s\n", err.Error())&nbsp; &nbsp; &nbsp; &nbsp; os.Exit(2)&nbsp; &nbsp; }&nbsp; &nbsp; defer tty.Close()&nbsp; &nbsp; // Write a command&nbsp; &nbsp; cmd := "echo Hello from go, pid = $$\n"&nbsp; &nbsp; cmdstr := C.CString(cmd)&nbsp; &nbsp; cmdaddr := uintptr(unsafe.Pointer(cmdstr))&nbsp; &nbsp; for i := range []byte(cmd) {&nbsp; &nbsp; &nbsp; &nbsp; _, _, err := syscall.Syscall(syscall.SYS_IOCTL, tty.Fd(), syscall.TIOCSTI, cmdaddr+uintptr(i))&nbsp; &nbsp; &nbsp; &nbsp; if uintptr(err) != 0 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("syscall error: %s\n", err.Error())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; os.Exit(3)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}这是一个示例输出:$ echo $$70318$ ./foo&nbsp;Running from foo script, pid = 83035echo Hello from go, pid = $$$ echo Hello from go, pid = $$Hello from go, pid = 70318请注意,我正在使用./not执行脚本source,因此脚本的 PID 不同。但是后来,go程序执行的命令有相同的PID。
随时随地看视频慕课网APP

相关分类

Go
我要回答