我们如何在Go中执行更改命令名称argv0的命令?

问题描述 投票:0回答:1

使用 os/exec 或 golang.org/x/sys/unix 包执行命令时, 我们如何执行更改命令名称 argv0 的命令,如

exec
-a
选项?

例如

exec -a assumego granted "$@" # Execute granted as assumego

我希望我们可以通过更改

exec.Cmd.Args[0]
unix.Exec's argv[0]
来更改命令名称,但它们不起作用。

脚本

foo
:

#!/usr/bin/env bash

set -eu

echo "0: $0"
echo "@: $@"

echo foo

main.go 使用 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
}

运行main.go,但$0没有改变。

$ go run main.go
0: ./foo
@: a b
foo

main.go 使用 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
}

运行main.go,但$0没有改变。

$ go run main.go
0: ../foo
@: a b
foo

参考:

背景:

go
1个回答
0
投票

我不确定它是什么时候引入的,但是在当前版本的 bash 中,您可以设置/导出

BASH_ARGV0
https://www.man7.org/linux/man-pages/man1/bash.1.html

但是,如果您需要支持旧版本的 bash,例如 Mac 上的 3.2 版本,则此功能不可用。

Zsh 允许直接设置

0
。 Posix shell 没有执行此操作的方法。


我(现在已经多次)使用过一个“黑客”来解决这个问题,它可以与 shell 脚本以及可执行文件一起使用,它是使用我想要的名称作为 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

这允许很多有趣的模式,例如可以重定向到其他可执行文件的“调度”可执行文件。根据用例,这些符号链接也可以按需创建并在执行后清理。

© www.soinside.com 2019 - 2024. All rights reserved.