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.") } }