我想在golang程序中运行交互式shell脚本, 例如包装“ ping 8.8.8.8”,“ python”,“ bc”,“ mysql -H -P -u -p”。 当golang程序本身完成调用交互式命令或shell并与用户进行交互时,应退出该程序。
我尝试了“ exec.Command(“ python”)。Run()“,但是golang程序刚刚完成,什么也没给我。
func (h ConnectHandler)ConnectMySQL() {
logrus.Debug("ConnectMySQL, script:",common.CONF.FilePath.MySQLConnectScriptPath)
err :=exec.Command("bash",common.CONF.FilePath.MySQLConnectScriptPath).Run()
if err != nil{
logrus.Errorf("ConnectMySQL failed, exit 1,%s",err)
os.Exit(1)
}
}
答案 0 :(得分:1)
将命令的stdin,stdout和stderr连接到父进程的stdin,stdout和stderr。另外,在-c
中向exec.Command
提供bash
,否则bash
会尝试像运行shell脚本一样运行程序。
例如,启动交互式Python控制台:
func main() {
fmt.Println("Before Python shell:")
cmd := exec.Command("bash", "-c", "/usr/bin/python3")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
_ = cmd.Run() // add error checking
fmt.Println("After Python shell")
}
答案 1 :(得分:0)
听起来您想用尝试启动的命令替换当前进程。启动另一个命令后,Go程序消失了,调用者与启动的程序进行交互,就好像它是最初启动的东西一样。
为此,您需要低级syscall.Exec函数。通常,您不应该期望它返回。请注意,您需要提供许多详细信息,例如要运行的实际二进制文件以及高级包装程序不需要的环境。 (非常快速的Google搜索找到了this detailed writeup。)
import "os"
import "syscall"
err := syscall.Exec("/bin/ls", []string{"ls", "-l", "/"}, os.Environ())
// We don't expect this to ever return; if it does something is really wrong
os.panic(err)
就底层Unix系统调用而言,诸如os.StartProcess
和exec.Cmd
之类的更高级别的接口都是 fork (2)先于在那个孩子中执行(2)。当您的Go进程退出时,该子进程将成为孤立的,并且系统初始化进程将成为其新的父进程。该外壳程序仅看到Go进程已退出,并会产生一个新的外壳程序提示。