package main
import (
"bytes"
"os/exec"
"fmt"
"context"
"time"
"syscall"
)
func main() {
var (
cmd *exec.Cmd
//output []byte
//err error
)
ctx, cancelFunc := context.WithCancel(context.Background())
go func() {
// 生成Cmd
cmd = exec.CommandContext(ctx, "/bin/bash", "-c", "/usr/bin/php ./b.php")
cmd.SysProcAttr = &syscall.SysProcAttr{}
var b bytes.Buffer
cmd.Stdout = &b //剧透,坑在这里
cmd.Stderr = &b
if err := cmd.Start(); err != nil {
fmt.Println(err)
return
}
// 超时杀掉进程组 或正常退出
go func() {
select {
case <-ctx.Done():
fmt.Println( cmd.Process.Pid)
}
}()
if err := cmd.Wait(); err != nil {
fmt.Println(err)
fmt.Println("recive: ", b.String())
return
}
fmt.Println("recive: ", b.String())
}()
time.Sleep(time.Second*20)
cancelFunc()
fmt.Println(9999999)
// 打印子进程的输出
time.Sleep(time.Second*1000)
}
b.php 会运行1500秒后才会停止
<?php
$a = true;
while ($a) {
for($i=1;$i<=1500;$i++){
sleep(1);
if($i == 1500){
$a = false;
}
}
}
echo 5566;
exit;
go run ./main.go
同时查看进程运行状态
ps -aux|grep b.php
[root@serv-test etcd-v3.3.13-linux-amd64]# ps -aux|grep b.php
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 17758 0.0 0.0 263856 11532 pts/2 S+ 16:56 0:00 /usr/bin/php ./b.php
root 18069 0.0 0.0 103340 920 pts/1 S+ 16:56 0:00 grep b.php
当20秒过后 golang程序会停止执行该任务 同时打印出了pid进程号
[root@serv-test golang-test]# go run ./main.go
开始
9999999
17758
signal: killed
再次查看pid进程状态 发现进程已经不存在了
[root@serv-test etcd-v3.3.13-linux-amd64]# ps -aux|grep b.php
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 26397 0.0 0.0 103336 916 pts/1 S+ 17:00 0:00 grep b.php