1
0
Fork 0
mirror of https://github.com/seqizz/go-tools.git synced 2024-09-07 10:50:30 +02:00

Add watchy

This commit is contained in:
Gürkan 2024-07-24 12:03:17 +02:00
parent c1d4241aaf
commit 1a5c653324
2 changed files with 118 additions and 0 deletions

View file

@ -9,6 +9,8 @@ Collection of tools I've written in golang
- **sshit**: Parallel ssh runner with config file support
- **watchy**: A simple "watch -n" like tool, with instant-refresh support
- **wwn**: Shows FC wwn's of a Linux system
- **wpmedia2hugo**: A helper program for parsing a wordpress blog's xml output to Hugo markdown

116
watchy/watchy.go Normal file
View file

@ -0,0 +1,116 @@
package main
import (
"bytes"
"flag"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"github.com/nsf/termbox-go"
)
func main() {
// Define and parse command-line flags
interval := flag.Int("n", 2, "Specify update interval in seconds")
flag.Parse()
// Check if there's a command to run
if len(flag.Args()) < 1 {
fmt.Println("Usage: program -n <seconds> '<shell command>'")
os.Exit(1)
}
// Get the user's shell, most meaningful way I can think of is $SHELL
// and no '/bin/sh' or '/bin/bash' hardcoding is not good (see NixOS)
shell := os.Getenv("SHELL")
if shell == "" {
fmt.Println("Error: Unable to determine shell. Please set the SHELL environment variable.")
os.Exit(1)
}
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
eventQueue := make(chan termbox.Event)
go func() {
for {
eventQueue <- termbox.PollEvent()
}
}()
ticker := time.NewTicker(time.Duration(*interval) * time.Second)
defer ticker.Stop()
binaryName := filepath.Base(os.Args[0])
command := strings.Join(flag.Args(), " ")
hintLine := "Press Ctrl-C to quit, any other key to refresh instantly"
update := func() {
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
// Get current time for refresh timestamp
refreshTime := time.Now().Format("15:04:05")
// Display header with refresh time
headerLine := fmt.Sprintf("%s: Running command every %d seconds: %s (last refresh: %s)",
binaryName, *interval, command, refreshTime)
displayLine(0, headerLine, termbox.ColorYellow, termbox.ColorDefault)
displayLine(1, hintLine, termbox.ColorCyan, termbox.ColorDefault)
// Execute the command and capture its output
output, err := executeShellCommand(shell, command)
if err != nil {
output = []byte(err.Error())
}
// Display the output
lines := splitLines(string(output))
for y, line := range lines {
displayLine(y+3, line, termbox.ColorDefault, termbox.ColorDefault)
}
termbox.Flush()
}
update()
for {
select {
case ev := <-eventQueue:
if ev.Type == termbox.EventKey {
if ev.Key == termbox.KeyCtrlC {
return
}
update()
}
case <-ticker.C:
update()
}
}
}
func executeShellCommand(shell, command string) ([]byte, error) {
cmd := exec.Command(shell, "-c", command)
var out bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &out
err := cmd.Run()
return out.Bytes(), err
}
func splitLines(s string) []string {
return strings.Split(strings.TrimSpace(s), "\n")
}
func displayLine(y int, s string, fg, bg termbox.Attribute) {
for x, ch := range s {
termbox.SetCell(x, y, ch, fg, bg)
}
}