Reputation: 91
When executing a command using os/exec or golang.org/x/sys/unix packages,
How can we execute a command changing the command name argv0 like exec
's -a
option?
e.g.
exec -a assumego granted "$@" # Execute granted as assumego
I expected we could change the command name by changing exec.Cmd.Args[0]
or unix.Exec's argv[0]
, but they didn't work.
A script foo
:
#!/usr/bin/env bash
set -eu
echo "0: $0"
echo "@: $@"
echo foo
main.go using os/exec:
package main
import (
"log"
"os"
"os/exec"
)
func main() {
if err := core(); err != nil {
log.Fatal(err)
}
}
func core() error {
cmd := exec.Command("./foo", "a", "b")
cmd.Args[0] = "bar"
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
return nil
}
Run main.go, but $0 isn't changed.
$ go run main.go
0: ./foo
@: a b
foo
main.go using golang.org/x/sys/unix:
package main
import (
"log"
"os"
"golang.org/x/sys/unix"
)
func main() {
if err := core(); err != nil {
log.Fatal(err)
}
}
func core() error {
return unix.Exec("../foo", []string{"bar", "a", "b"}, os.Environ()) //nolint:wrapcheck
}
Run main.go, but $0 isn't changed.
$ go run main.go
0: ../foo
@: a b
foo
Reference:
Background:
Upvotes: 4
Views: 130
Reputation: 61
I'm not sure exactly when it was introduced, but in the current versions of bash, you can set/export BASH_ARGV0
. https://www.man7.org/linux/man-pages/man1/bash.1.html
If you need to support older versions of bash, though, like the 3.2 version on Mac, this is not available.
Zsh allows setting 0
directly. Posix shell does not have a method for doing this.
One "hack" that I've used (many times now) to get around this, which works with shell scripts as well as executables, is creating symlinks with the name I want as argv[0].
bash-3.2$ echo -e '#!/bin/sh\necho "$(basename "$0")" "$@"' >tmp.sh \
&& chmod +x tmp.sh \
&& ./tmp.sh hello world \
&& ln -s tmp.sh foo \
&& ./foo hello world
tmp.sh hello world
foo hello world
This allows for a lot of fun patterns like a "dispatch" executable that can redirect to other executables. Depending on the usecase, these symlinks can also be created on demand and cleaned up after execution.
Upvotes: 1