Initial commit
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CmdOutString(name string, arg ...string) (string, error) {
|
||||
bs, err := CmdOutBytes(name, arg...)
|
||||
if err != nil {
|
||||
return "", errors.New(fmt.Sprintf("CmdOutBytes get error : %v", err))
|
||||
}
|
||||
|
||||
return string(bs), nil
|
||||
}
|
||||
|
||||
func CmdOutBytes(name string, arg ...string) ([]byte, error) {
|
||||
cmd := exec.Command(name, arg...)
|
||||
return cmd.CombinedOutput()
|
||||
}
|
||||
|
||||
func CmdOutTrim(name string, arg ...string) (string, error) {
|
||||
out, err := CmdOutString(name, arg...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return strings.TrimSpace(string(out)), nil
|
||||
}
|
||||
|
||||
func CmdRun(name string, arg ...string) error {
|
||||
cmd := exec.Command(name, arg...)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// CmdRunT Command run with timeout
|
||||
func CmdRunT(timeout time.Duration, name string, arg ...string) (output string, err error, istimeout bool) {
|
||||
cmd := exec.Command(name, arg...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
var b bytes.Buffer
|
||||
cmd.Stdout = &b
|
||||
cmd.Stderr = &b
|
||||
|
||||
cmd.Start()
|
||||
err, istimeout = WrapTimeout(cmd, timeout)
|
||||
output = b.String()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func WrapTimeout(cmd *exec.Cmd, timeout time.Duration) (error, bool) {
|
||||
var err error
|
||||
done := make(chan error)
|
||||
go func() {
|
||||
done <- cmd.Wait()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(timeout):
|
||||
go func() {
|
||||
<-done // allow goroutine to exit
|
||||
}()
|
||||
|
||||
// IMPORTANT: cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} is necessary before cmd.Start()
|
||||
// err = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
||||
err = cmd.Process.Kill()
|
||||
return fmt.Errorf("cmd kill process %w", err), true
|
||||
case err = <-done:
|
||||
return err, false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CmdOutString(name string, arg ...string) (string, error) {
|
||||
bs, err := CmdOutBytes(name, arg...)
|
||||
if err != nil {
|
||||
return "", errors.New(fmt.Sprintf("CmdOutBytes get error : %v", err))
|
||||
}
|
||||
|
||||
return string(bs), nil
|
||||
}
|
||||
|
||||
func CmdOutBytes(name string, arg ...string) ([]byte, error) {
|
||||
cmd := exec.Command(name, arg...)
|
||||
return cmd.CombinedOutput()
|
||||
}
|
||||
|
||||
func CmdOutTrim(name string, arg ...string) (string, error) {
|
||||
out, err := CmdOutString(name, arg...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return strings.TrimSpace(string(out)), nil
|
||||
}
|
||||
|
||||
func CmdRun(name string, arg ...string) error {
|
||||
cmd := exec.Command(name, arg...)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// CmdRunT Command run with timeout
|
||||
func CmdRunT(timeout time.Duration, name string, arg ...string) (output string, err error, istimeout bool) {
|
||||
cmd := exec.Command(name, arg...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
var b bytes.Buffer
|
||||
cmd.Stdout = &b
|
||||
cmd.Stderr = &b
|
||||
|
||||
cmd.Start()
|
||||
err, istimeout = WrapTimeout(cmd, timeout)
|
||||
output = b.String()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func WrapTimeout(cmd *exec.Cmd, timeout time.Duration) (error, bool) {
|
||||
var err error
|
||||
done := make(chan error)
|
||||
go func() {
|
||||
done <- cmd.Wait()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(timeout):
|
||||
go func() {
|
||||
<-done // allow goroutine to exit
|
||||
}()
|
||||
|
||||
// IMPORTANT: cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} is necessary before cmd.Start()
|
||||
// err = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
||||
err = cmd.Process.Kill()
|
||||
return fmt.Errorf("cmd kill process %w", err), true
|
||||
case err = <-done:
|
||||
return err, false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CmdOutString(name string, arg ...string) (string, error) {
|
||||
bs, err := CmdOutBytes(name, arg...)
|
||||
if err != nil {
|
||||
return "", errors.New(fmt.Sprintf("CmdOutBytes get error : %v", err))
|
||||
}
|
||||
|
||||
return string(bs), nil
|
||||
}
|
||||
|
||||
func CmdOutBytes(name string, arg ...string) ([]byte, error) {
|
||||
cmd := exec.Command(name, arg...)
|
||||
return cmd.CombinedOutput()
|
||||
}
|
||||
|
||||
func CmdOutTrim(name string, arg ...string) (string, error) {
|
||||
out, err := CmdOutString(name, arg...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return strings.TrimSpace(string(out)), nil
|
||||
}
|
||||
|
||||
func CmdRun(name string, arg ...string) error {
|
||||
cmd := exec.Command(name, arg...)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// CmdRunT Command run with timeout
|
||||
func CmdRunT(timeout time.Duration, name string, arg ...string) (output string, err error, istimeout bool) {
|
||||
cmd := exec.Command(name, arg...)
|
||||
// cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
HideWindow: true,
|
||||
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
|
||||
}
|
||||
var b bytes.Buffer
|
||||
cmd.Stdout = &b
|
||||
cmd.Stderr = &b
|
||||
|
||||
cmd.Start()
|
||||
err, istimeout = WrapTimeout(cmd, timeout)
|
||||
output = b.String()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func WrapTimeout(cmd *exec.Cmd, timeout time.Duration) (error, bool) {
|
||||
var err error
|
||||
done := make(chan error)
|
||||
go func() {
|
||||
done <- cmd.Wait()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(timeout):
|
||||
go func() {
|
||||
<-done // allow goroutine to exit
|
||||
}()
|
||||
|
||||
// IMPORTANT: cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} is necessary before cmd.Start()
|
||||
// err = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
||||
err = cmd.Process.Kill()
|
||||
return fmt.Errorf("cmd kill process %w", err), true
|
||||
case err = <-done:
|
||||
return err, false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func KillProcessByCmdline(cmdline string) error {
|
||||
cmdline = strings.TrimSpace(cmdline)
|
||||
if cmdline == "" {
|
||||
return fmt.Errorf("cmdline is blank")
|
||||
}
|
||||
|
||||
pids := PidsByCmdline(cmdline)
|
||||
for i := 0; i < len(pids); i++ {
|
||||
out, err := CmdOutTrim("kill", "-9", strconv.Itoa(pids[i]))
|
||||
if err != nil {
|
||||
return fmt.Errorf("kill -9 %d fail: %v, output: %s", pids[i], err, out)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func IntranetIP() (ips []string, err error) {
|
||||
ips = make([]string, 0)
|
||||
|
||||
ifaces, e := net.Interfaces()
|
||||
if e != nil {
|
||||
return ips, e
|
||||
}
|
||||
|
||||
for _, iface := range ifaces {
|
||||
if iface.Flags&net.FlagUp == 0 {
|
||||
continue // interface down
|
||||
}
|
||||
|
||||
if iface.Flags&net.FlagLoopback != 0 {
|
||||
continue // loopback interface
|
||||
}
|
||||
|
||||
// ignore docker and warden bridge
|
||||
if strings.HasPrefix(iface.Name, "docker") || strings.HasPrefix(iface.Name, "w-") {
|
||||
continue
|
||||
}
|
||||
|
||||
addrs, e := iface.Addrs()
|
||||
if e != nil {
|
||||
return ips, e
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
}
|
||||
|
||||
if ip == nil || ip.IsLoopback() {
|
||||
continue
|
||||
}
|
||||
|
||||
ip = ip.To4()
|
||||
if ip == nil {
|
||||
continue // not an ipv4 address
|
||||
}
|
||||
|
||||
ipStr := ip.String()
|
||||
if IsIntranet(ipStr) {
|
||||
ips = append(ips, ipStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ips, nil
|
||||
}
|
||||
|
||||
func IsIntranet(ipStr string) bool {
|
||||
if strings.HasPrefix(ipStr, "10.") {
|
||||
return true
|
||||
}
|
||||
|
||||
// for didi
|
||||
if strings.HasPrefix(ipStr, "100.") {
|
||||
return true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(ipStr, "192.168.") {
|
||||
return true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(ipStr, "172.") {
|
||||
// 172.16.0.0-172.31.255.255
|
||||
arr := strings.Split(ipStr, ".")
|
||||
if len(arr) != 4 {
|
||||
return false
|
||||
}
|
||||
|
||||
second, err := strconv.ParseInt(arr[1], 10, 64)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if second >= 16 && second <= 31 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ${sn}-${hostname}-${ip}
|
||||
func LocalHostIdent() string {
|
||||
sn, _ := CmdOutTrim("/bin/bash", "-c", "dmidecode -s system-serial-number")
|
||||
if sn != "" {
|
||||
arr := strings.Fields(sn)
|
||||
sn = arr[len(arr)-1]
|
||||
} else {
|
||||
sn = "nil"
|
||||
}
|
||||
|
||||
name, _ := CmdOutTrim("hostname")
|
||||
|
||||
ips, _ := IntranetIP()
|
||||
ip := ""
|
||||
if ips != nil && len(ips) > 0 {
|
||||
ip = ips[0]
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s-%s-%s", sn, name, ip)
|
||||
}
|
||||
|
||||
func GetOutboundIpaddr() string {
|
||||
conn, err := net.Dial("udp4", "1.2.3.4:56")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
localAddr := conn.LocalAddr().String()
|
||||
|
||||
if ip, _, err := net.SplitHostPort(localAddr); err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return ip
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"pet-house.com/core/helper/dir"
|
||||
)
|
||||
|
||||
func PidsByCmdline(cmdline string) []int {
|
||||
ret := []int{}
|
||||
|
||||
var dirs []string
|
||||
dirs, err := dir.DirsUnder("/proc")
|
||||
if err != nil {
|
||||
return ret
|
||||
}
|
||||
|
||||
count := len(dirs)
|
||||
for i := 0; i < count; i++ {
|
||||
pid, err := strconv.Atoi(dirs[i])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
cmdlineFile := fmt.Sprintf("/proc/%d/cmdline", pid)
|
||||
if !dir.IsExist(cmdlineFile) {
|
||||
continue
|
||||
}
|
||||
|
||||
cmdlineBytes, err := dir.ReadBytes(cmdlineFile)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
cmdlineBytesLen := len(cmdlineBytes)
|
||||
if cmdlineBytesLen == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
noNut := make([]byte, 0, cmdlineBytesLen)
|
||||
for j := 0; j < cmdlineBytesLen; j++ {
|
||||
if cmdlineBytes[j] != 0 {
|
||||
noNut = append(noNut, cmdlineBytes[j])
|
||||
}
|
||||
}
|
||||
|
||||
if strings.Contains(string(noNut), cmdline) {
|
||||
ret = append(ret, pid)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
Reference in New Issue
Block a user