71 lines
2.1 KiB
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.")
|
|
}
|
|
}
|