Think about you begin a long-running course of. It could take a number of minutes to finish. The method gives output (stdout/stderr), that you could analyse, and supply your person some data/report on the method’ progress (eg. how a lot job has been already performed). You need (1) to watch the method, and to supply such progress standing, and (2) detect when the method has been completed (in any means: it’s not lively). That’s all I would like/must do.
I made a easy experiment. I wrote the next Bash script:
for i in `seq 10`; do
sleep 5
echo $i
performed
It’s a easy course of, that counts as much as 10, with some delay earlier than counting up every quantity. It simulates a long-running course of, which will likely be accomplished with none interruptions.
Now, I needed a Go program, that:
(1) begins the method (the Bash script),
(2) studies the final quantity counted,
(3) detects, that the began course of has been accomplished.
And all of this, with none blocking, since reporting could be ship to different providers/goroutines.
I ended up with the next code:
func processStatus(pid int) string {
str_pid := strconv.Itoa(pid)
cmd := exec.Command("ps", "-q", str_pid, "-o", "state", "--no-headers")
var out strings.Builder
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
log.Deadly(err)
}
return out.String()
}
func important() {
// arrange the command
cmd := exec.Command("./test1.sh")
var out strings.Builder
cmd.Stdout = &out
// begin the command
err := cmd.Begin()
if err != nil {
log.Deadly(err)
}
fmt.Println("Command has been began...")
// look forward to the command/course of to complete
for strings.HasPrefix(processStatus(cmd.Course of.Pid), "S") {
fmt.Println("...command nonetheless operating")
// report the progress
arr := strings.Break up(out.String(), "n")
if len(arr) > 1 {
fmt.Println( arr[ len(arr) - 2 ] )
} else if len(arr) == 1 {
fmt.Println( arr[0] )
}
// simply to scrub up the output a little bit
out.Reset()
// we do not know
time.Sleep(5 * time.Second)
}
err = cmd.Wait()
if err != nil {
log.Deadly(err)
}
What I came upon, is the very fact, that for those who begin the command utilizing the cmd.Begin()
, after it completes, it doesn’t create the cmd.ProcessState
struct/area. So I needed to verify for the method standing with the ps
system command.