
本文详解如何将 shell 命令的标准输出(如 `ls /bin`)按行分割为字符串切片,并序列化为标准 json 数组格式,涵盖字符串处理、json 编码及常见边界问题的处理。
在 Go 中,将外部命令输出(如 ls /bin)转化为结构化数据(如 JSON 数组)是一个典型场景,常用于 API 响应、配置生成或跨语言数据交换。核心步骤包括:执行命令 → 捕获输出 → 按行解析为切片 → 序列化为 JSON。
以下是一个完整、健壮的实现示例:
package main
import (
"encoding/json"
"fmt"
"os/exec"
"strings"
)
func main() {
// 1. 执行命令并获取原始输出
cmd := exec.Command("ls", "/bin")
out, err := cmd.Output()
if err != nil {
fmt.Printf("命令执行失败: %v\n", err)
return
}
// 2. 转换为字符串并按换行符分割(注意:末尾可能含空行)
outputStr := string(out)
lines := strings.Split(outputStr, "\n")
// 3. 过滤空字符串(避免因末尾换行导致 []string 中出现空元素)
var filtered []string
for _, line := range lines {
if line != "" {
filtered = append(filtered, line)
}
}
// 4. 序列化为 JSON 数组
jsonBytes, err := json.Marshal(filtered)
if err != nil {
fmt.Printf("JSON 序列化失败: %v\n", err)
return
}
// 5. 输出结果(标准 JSON 格式,无多余空格)
fmt.Println(string(jsonBytes))
// 示例输出: ["unicode_start","unicode_stop","unlink","usleep","vi","view","ypdomainname","zcat"]
}✅ 关键说明与最佳实践:
- strings.Split(..., "\n") 是最直接的行分割方式,但需注意:cmd.Output() 返回的字节流末尾通常包含 \n,会导致最后一个元素为空字符串 —— 必须显式过滤;
- 使用 json.Marshal() 生成紧凑、合法的 JSON;若需美化输出(带缩进),可改用 json.MarshalIndent(filtered, "", " ");
- 错误处理不可省略:命令失败(如路径不存在)、编码失败(如含不可序列化类型)均需检查 err,生产环境严禁忽略;
- 替代方案提示:若目标是进一步处理(而非仅输出 JSON),可直接操作 filtered 切片(如排序、去重、筛选),再统一编码;
- 安全提醒:避免拼接用户输入构造 exec.Command 参数,防止命令注入;此处参数为硬编码字符串,属安全用法。
最终输出严格符合 JSON 规范:字符串数组,双引号包裹,逗号分隔,无尾随逗号 —— 可被 JavaScript、Python、Java 等任意支持 JSON 的语言无缝解析。










