duaevb1511 2018-11-14 08:47
浏览 34

从带有参数的字符串运行命令

I am trying to run a command with go. The command is in a string.

package main

import (
    "log"
    "os"
    "os/exec"
    "strings"

    "github.com/davecgh/go-spew/spew"
)

func main() {
    commandToRun := `echo $HOME`

    log.Printf("Running %s
", commandToRun)

    args := strings.Fields(commandToRun)
    spew.Dump(args[1:len(args)])
    command := exec.Command(args[0], args[1:len(args)]...)
    command.Stdout = os.Stdout
    command.Stdin = os.Stdin
    command.Stderr = os.Stderr
    err := command.Run()

    if err != nil {
        log.Printf("Command finished with error: %v", err)
    }
}

The output is:

2018/11/14 09:41:22 Running echo $HOME
([]string) (len=1 cap=1) {
 (string) (len=5) "$HOME"
}
$HOME

What I'd like to have is:

2018/11/14 09:41:22 Running echo $HOME
([]string) (len=1 cap=1) {
 (string) (len=5) "$HOME"
}
/home/whatever

Looks like go is sanitizing the string somehow. So the $HOME is not expanded. Is there any way of running the string exactly as if it was typed into the shell?

This is the important part. Ideally I'd like to turn from string to type in the current shell.

EDIT: The example below solve the simplest scenario but doesn't cover the "running the string exactly as if it was typed into the shell" part.

If I switch to expandenv:

commandToRun := os.ExpandEnv(`echo "$HOME"`)

I get:

2018/11/14 11:45:44 Running echo "/Users/rafael"
([]string) (len=1 cap=1) {
 (string) (len=15) "\"/home/whatever\""
}
"/home/whatever"

What I'd get in the shell is:

$ > echo "$HOME"
/home/whatever

without the quotes.

This is close to what I want but not exactly it.

  • 写回答

3条回答 默认 最新

  • doufeng2877 2018-11-14 09:22
    关注

    $HOME (and all other env variables) are expanded by the shell. You're not executing a shell, so they don't get expanded.

    You need to look up the env variable directly in go, with something like:

    command := exec.Command("echo", os.Getenv("HOME"))
    

    or this:

    commandToRun := os.ExpandEnv("echo $HOME")
    command := exec.Command(strings.Fields(commandToRun)...)
    

    Note that this last approach won't work if $HOME expands to a string containing whitespace, so the os.Getenv method is generally safer/preferred for this use case.

    评论

报告相同问题?

悬赏问题

  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入