jeninh

scripting-with-go

0
0
# Install this skill:
npx skills add jeninh/ampskills-dotfile --skill "scripting-with-go"

Install specific skill from multi-skill repository

# 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.

# 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 [email protected]


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 (choose based on your shell):

// For dash (Debian/Ubuntu default):
//usr/bin/env go run "$0" "$@"; exit

// For bash/zsh (avoids gopls formatting complaints):
/**/usr/bin/env go run "$0" "$@"; exit;

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

Shell compatibility:
- /**/ syntax works in bash/zsh but NOT in dash
- // syntax works in dash but gopls will complain about formatting
- Check your /bin/sh: ls -l /bin/sh
- Use //usr/bin/env go to find go in PATH
- Use //usr/local/go/bin/go for absolute path

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 (or exit;) prevents shell from interpreting remaining Go code
  7. Shell normalizes //path to /path or /**/path to /path

Complete example

//usr/bin/env 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/bin/env 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/bin/env 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/bin/env 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

  • Using env finds go in PATH, making scripts more portable
  • Semicolon required in exit; with /**/ syntax (but not with //)
  • Avoid dependencies for maximum compatibility
  • Slower startup than interpreted languages (compilation time)

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.