Golang中exec.Command在命令行和程序运行返回结果不一致问题探讨

Golang中exec.Command在命令行和程序运行返回结果不一致问题探讨 我正在尝试从命令行获取JSON输出,但结果似乎无效。

output, err := exec.Command("/usr/sbin/system_profiler", "SPHardwareDataType", "-json").CombinedOutput()
    if err != nil {
        log.Println("/usr/sbin/system_profiler SPHardwareDataType -json", err, output)
    }
    fmt.Println(string(output))

这将返回以下数据:

 {
  "SPHardwareDataType" : [
    {
      "_name" : "hardware_overview",
      "activation_lock_status" : "activation_lock_disabled",
      "cpu_type" : "Unknown",
      "current_processor_speed" : "2,4 GHz",
      "l2_cache" : "8 MB",
      "machine_model" : "MacBookAir10,1",
      "machine_name" : "MacBook Air",
      "number_processors" : 8,
      "packages" : 1,
      "physical_memory" : "16 GB",
      "platform_UUID" : "6BF86BB5-A724-5D99-BC31-8C2E851C264E",
      "provisioning_UDID" : "6BF86BB5-A724-5D99-BC31-8C2E851C264E",
      "serial_number" : "C02DVC27Q6LR"
    }
  ]
}

如果我直接从命令行运行此命令,输出如下所示:

{
  "SPHardwareDataType" : [
    {
      "_name" : "hardware_overview",
      "activation_lock_status" : "activation_lock_disabled",
      "boot_rom_version" : "7429.41.5",
      "chip_type" : "Apple M1",
      "machine_model" : "MacBookAir10,1",
      "machine_name" : "MacBook Air",
      "number_processors" : "proc 8:4:4",
      "os_loader_version" : "7429.41.5",
      "physical_memory" : "16 GB",
      "platform_UUID" : "6BF86BB5-A724-5D99-BC31-8C2E851C264E",
      "provisioning_UDID" : "00008103-001538C026E2001E",
      "serial_number" : "C02DVC27Q6LR"
    }
  ]
}

也许你们中有人知道系统端是否存在任何限制。感谢帮助。


更多关于Golang中exec.Command在命令行和程序运行返回结果不一致问题探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复
{
  "SPHardwareDataType" : [
    {
      "_name" : "hardware_overview",
      "activation_lock_status" : "activation_lock_disabled",
      "boot_rom_version" : "7429.41.5",
      "chip_type" : "Apple M1",
      "machine_model" : "MacBookAir10,1",
      "machine_name" : "MacBook Air",
      "number_processors" : "proc 8:4:4",
      "os_loader_version" : "7429.41.5",
      "physical_memory" : "16 GB",
      "platform_UUID" : "6BF86BB5-A724-5D99-BC31-8C2E851C264E",
      "provisioning_UDID" : "00008103-001538C026E2001E",
      "serial_number" : "C02DVC27Q6LR"
    }
  ]
}

go版本 go版本 go1.17.6 darwin/amd64

go版本 go版本 go1.17.6 darwin/arm64

错误安装的软件包是导致此问题的根本原因 (darwin/amd64)

更多关于Golang中exec.Command在命令行和程序运行返回结果不一致问题探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个典型的exec.Command环境变量差异问题。system_profiler命令的输出会根据调用环境而变化,特别是当通过Go程序调用时,某些环境变量可能缺失或不同。

问题在于system_profiler命令在非交互式shell中运行时,会返回简化版本的硬件信息。以下是解决方案:

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "os"
    "os/exec"
)

func main() {
    // 方法1:设置完整的环境变量
    cmd := exec.Command("/usr/sbin/system_profiler", "SPHardwareDataType", "-json")
    
    // 复制当前进程的环境变量
    cmd.Env = os.Environ()
    
    // 添加可能需要的特定环境变量
    cmd.Env = append(cmd.Env, "TERM=xterm-256color")
    cmd.Env = append(cmd.Env, "HOME="+os.Getenv("HOME"))
    cmd.Env = append(cmd.Env, "USER="+os.Getenv("USER"))
    
    output, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatal("执行命令失败:", err, string(output))
    }
    
    // 验证JSON格式
    var data map[string]interface{}
    if err := json.Unmarshal(output, &data); err != nil {
        log.Fatal("JSON解析失败:", err)
    }
    
    fmt.Println(string(output))
}

或者使用更直接的方法,通过shell来执行命令:

package main

import (
    "fmt"
    "log"
    "os/exec"
)

func main() {
    // 方法2:通过shell执行,模拟终端环境
    cmd := exec.Command("sh", "-c", "/usr/sbin/system_profiler SPHardwareDataType -json")
    
    output, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatal("执行命令失败:", err, string(output))
    }
    
    fmt.Println(string(output))
}

对于需要完整硬件信息的场景,可以考虑使用system_profiler的详细模式:

package main

import (
    "fmt"
    "log"
    "os/exec"
)

func main() {
    // 方法3:使用详细输出模式
    cmd := exec.Command("/usr/sbin/system_profiler", "SPHardwareDataType", "-json", "-detailLevel", "full")
    
    output, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatal("执行命令失败:", err, string(output))
    }
    
    fmt.Println(string(output))
}

如果上述方法仍然无法获取完整信息,可以尝试使用ioreg命令作为替代方案:

package main

import (
    "fmt"
    "log"
    "os/exec"
)

func main() {
    // 方法4:使用ioreg获取硬件信息
    cmd := exec.Command("ioreg", "-l", "-w", "0")
    
    output, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatal("执行命令失败:", err, string(output))
    }
    
    fmt.Println(string(output))
}

这些方法应该能解决exec.Command在命令行和程序运行中返回结果不一致的问题。主要差异源于环境变量的设置和命令执行上下文的不同。

回到顶部