Тип exec.ExitError

Тип exec.ExitError представляет ошибку, которая возникает, когда выполняемая внешняя команда завершается с ненулевым кодом возврата. Этот тип реализует интерфейс error и содержит информацию о процессе, включая код выхода и состояние процесса. Обычно exec.ExitError возвращается методами Run, Output, CombinedOutput типа exec.Cmd, когда команда завершается с ошибкой.

Синтаксис

gotype ExitError struct {
  *os.ProcessState
  Stderr []byte
}

Структура ExitError содержит встроенное поле *os.ProcessState, которое предоставляет информацию о завершенном процессе, и поле Stderr, содержащее вывод стандартного потока ошибок команды.

Пример

Давайте попробуем выполнить команду, которая завершается с ошибкой, и обработаем ошибку типа exec.ExitError:

gopackage main

import (
  "exec"
  "fmt"
  "os"
)

func main() {
  cmd := exec.Command("ls", "/non-existent-directory")
  err := cmd.Run()

  if err != nil {
    if exitErr, ok := err.(*exec.ExitError); ok {
      fmt.Printf("Command failed with exit code: %d\n", exitErr.ExitCode())
      fmt.Printf("Process state: %s\n", exitErr.String())
    } else {
      fmt.Printf("Other error: %v\n", err)
    }
  }
}

Результат выполнения кода:

go"Command failed with exit code: 2"
"Process state: exit status 2"

Пример

Давайте получим вывод стандартного потока ошибок из exec.ExitError, используя метод Output:

gopackage main

import (
  "exec"
  "fmt"
)

func main() {
  cmd := exec.Command("go", "build", "invalid-package")
  output, err := cmd.CombinedOutput()

  if err != nil {
    if exitErr, ok := err.(*exec.ExitError); ok {
      fmt.Printf("Exit code: %d\n", exitErr.ExitCode())
      fmt.Printf("Stderr output: %s\n", string(exitErr.Stderr))
    }
  }

  fmt.Printf("Combined output: %s\n", string(output))
}

Результат выполнения кода:

go"Exit code: 1"
"Stderr output: can't load package: package invalid-package: cannot find package \"invalid-package\" in any of ..."
"Combined output: can't load package: package invalid-package: cannot find package \"invalid-package\" in any of ..."

Пример

Давайте проверим наличие ошибки через метод ExitCode и сравним код выхода с ожидаемым значением:

gopackage main

import (
  "exec"
  "fmt"
  "os"
)

func main() {
  cmd := exec.Command("false")
  err := cmd.Run()

  if err != nil {
    if exitErr, ok := err.(*exec.ExitError); ok {
      if exitErr.ExitCode() == 1 {
        fmt.Println("Command failed with expected exit code 1")
      } else {
        fmt.Printf("Unexpected exit code: %d\n", exitErr.ExitCode())
      }
    } else {
      fmt.Printf("Other error: %v\n", err)
    }
  }
}

Результат выполнения кода:

go"Command failed with expected exit code 1"

Пример

Давайте обработаем ошибку при выполнении команды с неверными аргументами и получим детальную информацию из exec.ExitError:

gopackage main

import (
  "exec"
  "fmt"
  "os"
)

func main() {
  cmd := exec.Command("echo", "-invalid-flag")
  output, err := cmd.Output()

  if err != nil {
    if exitErr, ok := err.(*exec.ExitError); ok {
      fmt.Printf("Error type: %T\n", exitErr)
      fmt.Printf("Exit code: %d\n", exitErr.ExitCode())
      fmt.Printf("Process state: %v\n", exitErr.ProcessState)
      fmt.Printf("Error message: %s\n", exitErr.Error())
    } else {
      fmt.Printf("Non-ExitError: %v\n", err)
    }
  }

  fmt.Printf("Output: %s\n", string(output))
}

Результат выполнения кода:

go"Error type: *exec.ExitError"
"Exit code: 2"
"Process state: &{...}"
"Error message: exit status 2"
"Output: "

Смотрите также

  • тип exec.Cmd,
    который представляет выполняемую внешнюю команду
  • функцию exec.Command,
    которая создает новую команду для выполнения
  • метод exec.Cmd.Run,
    который запускает команду и ожидает ее завершения
  • метод exec.Cmd.CombinedOutput,
    который выполняет команду и возвращает объединенный вывод