Golang processes: Difference between revisions

From wikinotes
Line 54: Line 54:
= Subprocess =
= Subprocess =
<blockquote>
<blockquote>
high-level/friendly
<syntaxhighlight lang="go">
<syntaxhighlight lang="go">
//  1. create command,
//  2. modify it's exec.Cmd struct (ex. stdin,stdout)
//  3. cmd.Start()
import "os"
import "os"
import "os/exec"
import "os/exec"


// low-level (inherited files, os-specific syscalls, etc.)
// likely want exec.* instead
psAttr := os.ProcAttr{
    Dir: "/var/tmp",
    Env: []string{"FOO=BAR"},
}
ps := os.StartProcess("netstat", []string{"-a", "-n"}, psAttr)
pstate, err := ps.Wait()
pstate.ExitCode()
</syntaxhighlight>
<syntaxhighlight lang="go">
import "os"
import "os/exec"
// high-level
//  1. create command,
//  2. modify it's exec.Cmd struct (ex. stdin,stdout)
//  3. cmd.Start()
cmd := exec.Command("netstat", "-an")
cmd := exec.Command("netstat", "-an")
stdout, err := cmd.Output()
stdout, err := cmd.Output()
Line 87: Line 72:
err := cmd.Start() // run, don't wait
err := cmd.Start() // run, don't wait
err := cmd.Wait()  // wait for proces to finish
err := cmd.Wait()  // wait for proces to finish
</syntaxhighlight>
low-level
<syntaxhighlight lang="go">
// 1. create ProcAttr
// 2. start process
// 3. wait for process
// 4. get info from it's ProcessState
import "os"
import "os/exec"
psAttr := os.ProcAttr{
    Dir: "/var/tmp",
    Env: []string{"FOO=BAR"},
}
ps := os.StartProcess("netstat", []string{"-a", "-n"}, psAttr)
pstate, err := ps.Wait()
pstate.ExitCode()
</syntaxhighlight>
</syntaxhighlight>
</blockquote><!-- Subprocess -->
</blockquote><!-- Subprocess -->

Revision as of 12:48, 26 June 2022

TODO:

  • signal handling
  • safely reading from stdin
  • piping outputs to inputs
  • what about exit codes?

Documentation

os https://pkg.go.dev/os@go1.18.3

Current Process

import "os"
import "os/user"

os.Executable()
os.Getpid()
os.Getppid()
os.Getuid()
os.Getgid()

os.Exit(1)              // exit process with exitcode '1'

// environment
envvars := os.Environ() // ["FOO=bar", "BAR=baz", ...]
pwd, err := os.Getwd()  // get current pwd/cwd
user.Current()          // 'will'

Manage Processes

import "syscall"
import "os"
import "os/signal"

proc := os.Process.FindProcess(1234)  // find process with pid
proc.Kill()                           // kill process (-9/SIGKILL)
proc.Signal(os.Iterrupt)              // send SIGINT to process (looks like you can use any syscall.SIG*)
proc.Wait()                           // wait for process to end

syscall.Kill(1234, syscall.SIGINT)    // send SIGINT to pid 1234

Subprocess

high-level/friendly

//   1. create command,
//   2. modify it's exec.Cmd struct (ex. stdin,stdout)
//   3. cmd.Start()
import "os"
import "os/exec"

cmd := exec.Command("netstat", "-an")
stdout, err := cmd.Output()

reader, err := cmd.StderrPipe()
reader, err := cmd.StdoutPipe()
writer, err := cmd.StdinPipe()

err := cmd.Run()   // run and wait
err := cmd.Start() // run, don't wait
err := cmd.Wait()  // wait for proces to finish

low-level

// 1. create ProcAttr
// 2. start process
// 3. wait for process
// 4. get info from it's ProcessState
import "os"
import "os/exec"

psAttr := os.ProcAttr{
    Dir: "/var/tmp",
    Env: []string{"FOO=BAR"},
}
ps := os.StartProcess("netstat", []string{"-a", "-n"}, psAttr)
pstate, err := ps.Wait()
pstate.ExitCode()

Process Info