Запустить интерактивный сценарий оболочки в программе golang

Я хочу запустить интерактивный сценарий 9X_go оболочки в программе golang, например, оберните 9X_go-language «ping 8.8.8.8», «python», «bc», «mysql -H 9X_go-language -P -u -p». Программа golang должна завершиться, когда 9X_golang сама завершит вызов интерактивной команды 9X_golang или оболочки и оставит порожденную интерактивную 9X_go с пользователем.

Я пробовал "exec.Command 9X_golang (" python "). Run()", но программа golang 9X_golang просто завершила работу и ничего мне не 9X_go оставила.

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)
    }
}

5
0
2
Общее количество ответов: 2

Ответ #1

Ответ на вопрос: Запустить интерактивный сценарий оболочки в программе golang

Подключите команды stdin, stdout и stderr 9X_go-language к таковым родительского процесса. Кроме 9X_go-language того, укажите -c в exec.Command в bash, иначе bash попытается 9X_go-language запустить вашу программу, как если бы это 9X_go-language сценарий оболочки.

Например, запуск интерактивной 9X_go консоли 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")
}

12
1

  • Этот метод работает отлично. Я не понимаю, почему он не получил голосов.<p><s ...

Ответ #2

Ответ на вопрос: Запустить интерактивный сценарий оболочки в программе golang

Похоже, вы хотите заменить текущий процесс 9X_go командой, которую пытаетесь запустить. После 9X_go того, как вы запустите другую команду, ваша 9X_go программа Go исчезнет, ​​и вызывающий абонент 9X_go будет взаимодействовать с запущенной программой, как 9X_go-language если бы она была изначально запущена.

Для 9X_go-language этого вам понадобится низкоуровневая функция 9X_golang syscall.Exec. Обычно не стоит ожидать его возвращения. Обратите 9X_go-language внимание, что вам необходимо предоставить 9X_golang ряд деталей, таких как фактический исполняемый 9X_go-language двоичный файл и среда, которая не нужна 9X_go оболочкам более высокого уровня. (Очень 9X_golang быстрый поиск в 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)

С точки 9X_go-language зрения базовых системных вызовов Unix, интерфейсы 9X_go более высокого уровня, такие как os.StartProcess и exec.Cmd, все 9X_go fork (2) являются дочерними процессами сначала 9X_golang перед execve (2) в этом ребенке. Когда ваш процесс 9X_go Go завершается, этот дочерний процесс становится 9X_go-language осиротевшим, а системный процесс инициализации становится 9X_go-language его новым родительским. Оболочка просто 9X_go видит, что процесс Go завершился, и выдает 9X_go-language новое приглашение оболочки.

2
1

  • В моем ответе нет «родительского процесса»; программа Go заменяется программой exec'd, а идентификатор родителя и процесса такие же, как и для программы ...