Пример на bash:
#!!! Что делает.
# Запускаеn run_command раз в секунду пока значения run_command_befor > run_command_befor_stop
# Далее спим и ничего не делаем sleep_time
# Когда проснулись начинаем выполнять команду run_command_2 пока значение run_command_after > run_command_after_stop
# Тут происходит сбрасывание счетчиков и возращение к выполнению run_command
# см переменные
cat > 0.txt << "EOF"
#!/bin/bash
#LOG
#set -xv
#VAR
export run_command_befor=0
export run_command_befor_stop=5
export sleep_time=2
export cicle_run=0
export run_command_after=0
export run_command_after_stop=5
export run_command="echo bu bu bu"
export run_command_2=$run_command
while :
do
$run_command
sleep 1
((run_command_befor++))
echo before sleep = $run_command_befor
if ((run_command_befor > $run_command_befor_stop )); then
((cicle_run++))
echo ================================================================ me sleep $sleep_time sec
sleep $sleep_time
while :
do
$run_command_2
sleep 1
((run_command_after++))
echo after sleep = $run_command_after
if ((run_command_after > $run_command_after_stop)); then
#exit 0
run_command_befor=0
run_command_after=0
echo =========================================================== run cicle command $cicle_run N
break
fi
done
fi
done
EOF
bash 0.txt
Сделать почти тоже самое на golang:
0. Создаем папку:
mkdir xrn
cd xrn
1. создаем конфиг для xrn
cat > config.conf << "EOF"
# комментарии начинаются с решётки
run_command=snmpwalk -n ctx_hades -v3 -a SHA1 -A authpassword -x AES128 -X privpassword -l authPriv -u snmpv3user 192.168.16.164 sysname
run_command2=
run_command_before_stop=5
run_command_after_stop=5
sleep_time_sec=2
step_sleep_sec=1
EOF
2. Создаем код программы:
cat > main.go << EOF
package main
import (
"bufio"
"flag"
"fmt"
"os"
"os/exec"
"strconv"
"strings"
"time"
)
type Config struct {
RunCommand string
RunCommand2 string
RunCommandBeforeStop int
RunCommandAfterStop int
SleepTimeSec int
StepSleepSec int
}
func loadConfig(path string) (*Config, error) {
f, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("open config: %w", err)
}
defer f.Close()
cfg := &Config{
// значения по умолчанию
RunCommandBeforeStop: 5,
RunCommandAfterStop: 5,
SleepTimeSec: 2,
StepSleepSec: 1,
}
sc := bufio.NewScanner(f)
for sc.Scan() {
line := strings.TrimSpace(sc.Text())
if line == "" || strings.HasPrefix(line, "#") {
continue // пропускаем пустые и комментарии
}
key, val, ok := strings.Cut(line, "=")
if !ok {
continue // строка без "=" — игнор
}
key = strings.TrimSpace(key)
val = strings.TrimSpace(val)
switch key {
case "run_command":
cfg.RunCommand = val
case "run_command2":
cfg.RunCommand2 = val
case "run_command_before_stop":
cfg.RunCommandBeforeStop, _ = strconv.Atoi(val)
case "run_command_after_stop":
cfg.RunCommandAfterStop, _ = strconv.Atoi(val)
case "sleep_time_sec":
cfg.SleepTimeSec, _ = strconv.Atoi(val)
case "step_sleep_sec":
cfg.StepSleepSec, _ = strconv.Atoi(val)
}
}
if err := sc.Err(); err != nil {
return nil, fmt.Errorf("scan config: %w", err)
}
if cfg.RunCommand2 == "" {
cfg.RunCommand2 = cfg.RunCommand
}
return cfg, nil
}
// run и main — такие же, как в JSON-варианте, меняется только loadConfig.
func run(cmdline string) {
cmd := exec.Command("sh", "-c", cmdline)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "command error: %v\n", err)
}
}
func main() {
configPath := flag.String("config", "config.conf", "путь к конфиг-файлу")
flag.Parse()
cfg, err := loadConfig(*configPath)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
stepSleep := time.Duration(cfg.StepSleepSec) * time.Second
sleepTime := time.Duration(cfg.SleepTimeSec) * time.Second
var (
runCommandBefore = 0
runCommandAfter = 0
cycleRun = 0
)
for {
run(cfg.RunCommand)
time.Sleep(stepSleep)
runCommandBefore++
fmt.Printf("before sleep = %d\n", runCommandBefore)
if runCommandBefore > cfg.RunCommandBeforeStop {
cycleRun++
fmt.Printf("================================================================ me sleep %v sec\n", sleepTime)
time.Sleep(sleepTime)
for {
run(cfg.RunCommand2)
time.Sleep(stepSleep)
runCommandAfter++
fmt.Printf("after sleep = %d\n", runCommandAfter)
if runCommandAfter > cfg.RunCommandAfterStop {
runCommandBefore = 0
runCommandAfter = 0
fmt.Printf("=========================================================== run cicle command %d N\n", cycleRun)
break
}
}
}
}
}
EOF
Делаем сборку:
go mod init xrn
#go get gopkg.in/yaml.v3
go build -o xrn .
./xrn -config config.yaml