golang按照UNIX Bourne shell规则解析字符串插件库shellwords的使用

Golang按照UNIX Bourne shell规则解析字符串插件库shellwords的使用

介绍

shellwords是一个Golang库,用于按照UNIX Bourne shell的单词解析规则来操作字符串。

安装

go get github.com/Wing924/shellwords

使用示例

导入库

import "github.com/Wing924/shellwords"

分割字符串

args, err := shellwords.Split("./foo --bar=baz")
// args 应该是 ["./foo", "--bar=baz"]

args, err := shellwords.Split("./foo 'a b c'")
// args 应该是 ["./foo", "a b c"]

合并字符串数组

line := shellwords.Join([]string{"abc", "d e f"})
// line 应该是 `abc d\ e\ f`

转义字符串

line := shellwords.Escape("./foo 'a b c'")
// line 应该是 `./foo\ \'a\ b\ c\'\"`

完整示例Demo

package main

import (
	"fmt"
	"github.com/Wing924/shellwords"
)

func main() {
	// 示例1:分割简单命令行
	args1, err1 := shellwords.Split("./cmd --option=value")
	if err1 != nil {
		fmt.Println("Error:", err1)
	} else {
		fmt.Println("Split Result 1:", args1)
		// 输出: ["./cmd", "--option=value"]
	}

	// 示例2:分割包含空格的参数
	args2, err2 := shellwords.Split(`./cmd "arg with spaces"`)
	if err2 != nil {
		fmt.Println("Error:", err2)
	} else {
		fmt.Println("Split Result 2:", args2)
		// 输出: ["./cmd", "arg with spaces"]
	}

	// 示例3:合并字符串数组
	joined := shellwords.Join([]string{"command", "arg with spaces", "$special"})
	fmt.Println("Joined Result:", joined)
	// 输出: command arg\ with\ spaces \$special

	// 示例4:转义字符串
	escaped := shellwords.Escape(`string with spaces and $special chars`)
	fmt.Println("Escaped Result:", escaped)
	// 输出: string\ with\ spaces\ and\ \$special\ chars
}

注意事项

  1. 该库基于Ruby模块Shellwords实现
  2. 完全遵循UNIX Bourne shell的解析规则
  3. 可以正确处理引号、转义字符和空格等特殊字符

这个库非常适合需要解析或生成shell命令行的Golang程序使用。


更多关于golang按照UNIX Bourne shell规则解析字符串插件库shellwords的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang按照UNIX Bourne shell规则解析字符串插件库shellwords的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang 的 shellwords 库使用指南

shellwords 是一个 Go 语言库,用于按照 UNIX Bourne shell 规则解析字符串,类似于 shell 解析命令行参数的方式。它能够正确处理引号、转义字符等情况。

安装

go get github.com/mattn/go-shellwords

基本用法

1. 解析字符串为参数列表

package main

import (
	"fmt"
	"github.com/mattn/go-shellwords"
)

func main() {
	// 示例字符串
	cmd := `git commit -m "commit message with spaces"`

	// 解析字符串
	args, err := shellwords.Parse(cmd)
	if err != nil {
		panic(err)
	}

	// 输出解析结果
	fmt.Println("解析后的参数:")
	for i, arg := range args {
		fmt.Printf("%d: %s\n", i, arg)
	}
}

输出结果:

解析后的参数:
0: git
1: commit
2: -m
3: commit message with spaces

2. 处理环境变量

package main

import (
	"fmt"
	"github.com/mattn/go-shellwords"
	"os"
)

func main() {
	// 设置环境变量
	os.Setenv("NAME", "Gopher")

	// 包含环境变量的字符串
	cmd := `echo "Hello, $NAME!"`

	// 创建解析器并启用环境变量解析
	p := shellwords.NewParser()
	p.ParseEnv = true

	// 解析字符串
	args, err := p.Parse(cmd)
	if err != nil {
		panic(err)
	}

	fmt.Println("解析后的参数:")
	for i, arg := range args {
		fmt.Printf("%d: %s\n", i, arg)
	}
}

输出结果:

解析后的参数:
0: echo
1: Hello, Gopher!

3. 处理带转义字符的字符串

package main

import (
	"fmt"
	"github.com/mattn/go-shellwords"
)

func main() {
	// 包含转义字符的字符串
	cmd := `echo "This is a \"quote\" inside"`

	args, err := shellwords.Parse(cmd)
	if err != nil {
		panic(err)
	}

	fmt.Println("解析后的参数:")
	for i, arg := range args {
		fmt.Printf("%d: %s\n", i, arg)
	}
}

输出结果:

解析后的参数:
0: echo
1: This is a "quote" inside

4. 处理多行命令

package main

import (
	"fmt"
	"github.com/mattn/go-shellwords"
)

func main() {
	// 多行命令
	cmd := `docker run \
		--name my-container \
		-p 8080:8080 \
		-v "$(pwd):/app" \
		my-image`

	args, err := shellwords.Parse(cmd)
	if err != nil {
		panic(err)
	}

	fmt.Println("解析后的参数:")
	for i, arg := range args {
		fmt.Printf("%d: %s\n", i, arg)
	}
}

输出结果:

解析后的参数:
0: docker
1: run
2: --name
3: my-container
4: -p
5: 8080:8080
6: -v
7: /current/working/directory:/app
8: my-image

高级用法

自定义解析行为

package main

import (
	"fmt"
	"github.com/mattn/go-shellwords"
)

func main() {
	// 自定义解析器
	p := shellwords.NewParser()
	
	// 设置解析选项
	p.ParseBacktick = true  // 解析反引号
	p.ParseEnv = true       // 解析环境变量
	p.ParseBackslash = true // 解析反斜杠转义

	cmd := `echo "Current dir is $(pwd) and user is $USER"`
	
	args, err := p.Parse(cmd)
	if err != nil {
		panic(err)
	}

	fmt.Println("解析后的参数:")
	for i, arg := range args {
		fmt.Printf("%d: %s\n", i, arg)
	}
}

处理解析错误

package main

import (
	"fmt"
	"github.com/mattn/go-shellwords"
)

func main() {
	// 包含未闭合引号的字符串
	cmd := `echo "unclosed quote`

	_, err := shellwords.Parse(cmd)
	if err != nil {
		fmt.Printf("解析错误: %v\n", err)
		// 处理错误逻辑...
	}
}

实际应用场景

  1. 命令行工具开发:解析用户输入的命令行字符串
  2. 配置解析:解析包含复杂参数的配置文件
  3. 脚本解释器:构建简单的 shell 解释器
  4. 容器/Docker 命令处理:解析复杂的容器运行命令

注意事项

  1. 默认情况下不解析环境变量,需要显式启用
  2. 反引号解析也需要显式启用
  3. 对于复杂的 shell 特性(如管道、重定向等),可能需要额外的处理

shellwords 库提供了简单而强大的功能,能够满足大多数 shell 风格字符串解析的需求,同时保持轻量级和易用性。

回到顶部