Closed suzuki-shunsuke closed 1 month ago
aqua executes commands by exec.Run
and unix.Exec
.
I thought we can change arg0 by changing exec.Cmd.Args[0]
and unix.Exec's argv[0]
, but it seems not to work.
#!/usr/bin/env bash
set -eu
echo "0: $0"
echo "@: $@"
echo foo
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
}
$ go run main.go
0: ./foo
@: a b
foo
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
}
$ go run main.go
0: ../foo
@: a b
foo
I asked some help in Stackoverflow.
Looks like to me if you set cmd.Path (in addition to cmd.Args[0] to avoid confusion) it works as expected?
Looks like to me if you set cmd.Path (in addition to cmd.Args[0] to avoid confusion) it works as expected?
Could you show me any example code?
package main
import (
"fmt"
"log"
"os"
"os/exec"
)
func main() {
cmd := exec.Command("ls", "-l")
cmd.Path = "/usr/bin/echo"
cmd.Args[0] = "echo"
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
fmt.Printf("DEBUG: %#v\n", cmd.Args)
}
❯ go run main.go
-l
DEBUG: []string{"echo", "-l"}
It seems ls
isn't executed.
$ go run main.go
2024/09/28 07:47:51 fork/exec /usr/bin/echo: no such file or directory
exit status 1
/usr/bin/echo
was executed.
Change Path to /usr/bin/ls then. Sorry, wasn't sure which direction was necessary here. Or am I still misunderstanding?
Ok yeah, I give up.
We want to change $0
when executing tools, but I'm not sure the way in Go, so I'm writing the simple code to look into it.
In the above code, I try to execute the shell script foo
changing $0
to bar
.
The script foo
outputs $0
, so I expect bar
is outputted, but it doesn't work as expected.
BTW, I got an answer in Stackoverflow, and changing Cmd.Args[0]
worked if the command is a single binary written in Go, not a bash script.
https://stackoverflow.com/questions/79029456/how-can-we-execute-a-command-changing-the-command-name-argv0-in-go?noredirect=1#comment139353340_79029456
https://gist.github.com/suzuki-shunsuke/6429c1f054ae06946e5ca6e923002592
I'm still not sure if we can change $0
of a shell script in Go.
Maybe we should consider creating links same as granted
's official installation guide if it's difficult to change $0
in Go.
e.g.
files:
- name: granted
- name: assume
- name: assumego
src: granted
link: assumego # Create a link to `src` in the same directory with `granted` and `aqua exec -- assumego` executes this link
Yeah I know this is an edge case, but perhaps supporting symlink functionality could be useful for other scenarios too.
@jpeeler Could you try aqua v2.36.0-1 on macOS?
mkdir test
cd test
aqua upa v2.36.0-1
echo "
registries:
- type: standard
ref: 2e36190cfe286029af7a2f9eb29bdd0e74a9f62c
packages:
- name: common-fate/granted@v0.34.1
" > aqua.yaml
aqua rm granted
aqua i
assume
I expect assume would work.
Yes, looks good to me!
Thank you!
aqua v2.36.0 and aqua-registry v4.227.0 is out 🎉
https://github.com/aquaproj/aqua/releases/tag/v2.36.0 https://github.com/aquaproj/aqua-registry/releases/tag/v4.227.0
Feature Overview
Enable us to change
$0
when executing tools likeexec
's-a
option.Why is the feature needed?
Some tools change their behavior by
$0
.For example,
granted
changes the behavior based onargs[0]
.https://github.com/common-fate/granted/blob/e8de3ec7d62d543062d8be802b27abb3d8fac429/cmd/granted/main.go#L37-L44
Workaround
Create shell scripts like this.
https://github.com/aquaproj/aqua-registry/issues/27177#issuecomment-2378009669
~/bin/assumego
Example Code
registry.yaml
Note
No response