SKILL.md


name: scripting-with-go description: Creates executable Go scripts with shebang-like behavior. Use when the user wants Go scripts, mentions Go scripting, or needs executable .go files. If working in a Go project, do NOT use unless explicitly requested. license: AGPL-3.0-or-later metadata: author: Amolith amolith@secluded.site

Create executable Go scripts using a shell trick (not a true shebang). Scripts run directly like ./script.go with full argument support.

Basic pattern

First line of any Go script:

/**/usr/local/go/bin/go run "$0" "$@"; exit;

Then chmod +x script.go and run ./script.go args.

How it works

  1. OS tries to execute ./script.go as binary
  2. Fails with ENOEXEC (not a binary)
  3. OS falls back to /bin/sh
  4. Shell runs first line: compiles and executes the script
  5. $0 = script path, $@ = all arguments
  6. exit; prevents shell from interpreting remaining Go code
  7. /**/ instead of // avoids gopls formatting complaints

Complete example

/**/usr/local/go/bin/go run "$0" "$@"; exit;
package main

import (
	"fmt"
	"os"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Usage: ./script.go <name>")
		os.Exit(1)
	}
	fmt.Printf("Hello, %s!\n", os.Args[1])
}

When to use

Good for:

  • Long-lived automation needing stability (Go 1.x compatibility guarantee)
  • Cross-platform scripts
  • Corporate environments
  • Scripts that may grow into programs
  • Avoiding dependency management hell

Avoid for:

  • Simple one-liners
  • Systems without Go
  • Throwaway scripts

Common patterns

CLI flags

/**/usr/local/go/bin/go run "$0" "$@"; exit;
package main

import (
	"flag"
	"fmt"
)

func main() {
	verbose := flag.Bool("v", false, "verbose output")
	flag.Parse()
	fmt.Printf("Verbose: %v, Args: %v\n", *verbose, flag.Args())
}

stdin

/**/usr/local/go/bin/go run "$0" "$@"; exit;
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		fmt.Println("Got:", scanner.Text())
	}
}

File operations

/**/usr/local/go/bin/go run "$0" "$@"; exit;
package main

import (
	"fmt"
	"os"
	"path/filepath"
)

func main() {
	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if !info.IsDir() {
			fmt.Println(path)
		}
		return nil
	})
}

Notes

  • Adjust /usr/local/go/bin/go if Go is elsewhere
  • Semicolon required in exit; with /**/ syntax
  • Avoid dependencies for maximum compatibility
  • Slower startup than interpreted languages (compilation time)