Skip to content

Instantly share code, notes, and snippets.

@sineemore
Created October 6, 2020 14:19
Show Gist options
  • Save sineemore/7f57d411f10197c16fdc1322441999df to your computer and use it in GitHub Desktop.
Save sineemore/7f57d411f10197c16fdc1322441999df to your computer and use it in GitHub Desktop.
watch w/o buffering
package main
import (
"context"
"flag"
"fmt"
"os"
"os/exec"
"os/signal"
"time"
)
func main() {
period := flag.Duration("n", time.Second*2, "time between command restarts")
flag.Parse()
args := flag.Args()
if len(args) < 1 {
fmt.Fprintln(os.Stderr, "no command specified")
os.Exit(1)
}
ctx, cancel := context.WithCancel(context.Background())
signals := make(chan os.Signal)
signal.Notify(signals, os.Interrupt)
go func() {
<-signals
fmt.Fprintln(os.Stderr, "received signal")
cancel()
}()
for {
cmd := exec.CommandContext(ctx, args[0], args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
doneC := make(chan struct{})
err := cmd.Start()
if err != nil {
fmt.Fprintf(os.Stderr, "failed to start command: %v\n", err)
} else {
go func() {
err := cmd.Wait()
if err != nil {
fmt.Fprintf(os.Stderr, "command error: %v\n", err)
}
close(doneC)
}()
select {
case <-doneC:
case <-ctx.Done():
return
}
}
if *period == 0 {
select {
case <-ctx.Done():
return
default:
}
continue
}
sleepC := time.After(*period)
select {
case <-sleepC:
case <-ctx.Done():
return
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment