Castor-Gemini/exec_with_title.go

71 lines
2.1 KiB
Go

package main
import (
"fmt"
"os/exec"
"strings"
)
// ExecWithTitle executes a command with a custom process title visible to `ps` on Linux.
// It uses `bash -c "exec -a ..."` to achieve this.
// title: The custom title for the process.
// commandAndArgs: The command and its arguments to execute.
func ExecWithTitle(title string, commandAndArgs ...string) error {
if len(commandAndArgs) == 0 {
return fmt.Errorf("no command provided to execute")
}
// The command to run is the first element.
command := commandAndArgs[0]
// The rest are its arguments.
args := commandAndArgs[1:]
// We need to construct the full command string for the shell.
// Using fmt.Sprintf with %q is a simple way to handle basic shell quoting.
// The final command will look like: exec -a 'My Title' 'sleep' '30'
fullCommand := fmt.Sprintf("exec -a %q %q %s",
title,
command,
strings.Join(quoteArgs(args), " "),
)
// The actual command we run is bash with the "-c" flag and our constructed string.
cmd := exec.Command("bash", "-c", fullCommand)
fmt.Printf("Running command: %s\n", cmd.String())
// Start the process.
err := cmd.Start()
if err != nil {
return fmt.Errorf("failed to start command: %w", err)
}
fmt.Printf("--> Process started with PID %d. Check 'ps aux | grep %d'.\n", cmd.Process.Pid, cmd.Process.Pid)
fmt.Println("--> The title should appear as:", title)
fmt.Println("Waiting for command to complete...")
// Wait for the command to complete.
return cmd.Wait()
}
// quoteArgs is a helper to wrap each argument in quotes for the shell.
func quoteArgs(args []string) []string {
quoted := make([]string, len(args))
for i, arg := range args {
quoted[i] = fmt.Sprintf("%q", arg)
}
return quoted
}
func main() {
fmt.Println("Starting a 'sleep 30' process with a custom title...")
fmt.Println("You will have 30 seconds to run 'ps' in another terminal to see it.")
err := ExecWithTitle("My Custom Sleeper (Job #42)", "sleep", "30")
if err != nil {
fmt.Printf("\nCommand finished with error: %v\n", err)
} else {
fmt.Println("\nCommand finished successfully.")
}
}