为了娱乐并更好地学习Go,我正在尝试在Go中重新实现抗原。
问题是:source是shell内置函数,所以我不能用os/exec Commandfunction 调用它,因为它希望在中有可执行文件PATH。
source
os/exec
Command
PATH
我怎样才能做到这一点?并且,是否有可能使sourcego程序内部的程序影响用户shell?
您可以直接在终端设备中编写命令。但是,要做到这一点,首先您需要知道哪个设备正在使用该用户。执行程序的脚本可能是解决方案。
#!/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。
./