golang简化DevOps和系统管理任务的Shell脚本编写插件script的使用

Golang简化DevOps和系统管理任务的Shell脚本编写插件script的使用

script是一个Go库,用于执行类似Shell脚本擅长完成的任务:读取文件、执行子进程、计数行数、匹配字符串等。它旨在让用Go编写系统管理程序变得像编写Shell脚本一样简单。

什么是script?

script是用于执行Shell脚本擅长任务的Go库。它采用类似Shell脚本的管道(pipeline)方式处理数据流。

Magical gopher logo

快速入门:Unix等效命令

如果你熟悉Shell脚本和Unix工具集,下表列出了常见Unix命令对应的script操作:

Unix / shell script等效
cat File / Concat
grep Match / MatchRegexp
grep -v Reject / RejectRegexp
head First
tail Last
wc -l CountLines
sed Replace / ReplaceRegexp
cut Column
curl Do / Get / Post

示例代码

读取文件内容

contents, err := script.File("test.txt").String()

统计文件行数

numLines, err := script.File("test.txt").CountLines()

统计匹配"Error"的行数

numErrors, err := script.File("test.txt").Match("Error").CountLines()

从标准输入过滤匹配行

script.Stdin().Match("Error").Stdout()

过滤并转换行

script.Stdin().Match("Error").FilterLine(strings.ToUpper).Stdout()

处理命令行参数文件

script.Args().Concat().Match("Error").Stdout()

只获取前10个匹配

script.Args().Concat().Match("Error").First(10).Stdout()

追加输出到文件

script.Args().Concat().Match("Error").First(10).AppendFile("/var/log/errors.txt")

同时输出到终端和文件

script.Echo("data").Tee().AppendFile("data.txt")

HTTP请求示例

script.Get("https://wttr.in/London?format=3").Stdout()
// 输出:
// London: 🌦   +13°C

自定义HTTP请求

req, err := http.NewRequest(http.MethodGet, "http://example.com", nil)
req.Header.Add("Authorization", "Bearer "+token)
script.Do(req).Stdout()

执行外部命令

script.Exec("ping 127.0.0.1").Stdout()

为每行输入执行命令

script.Args().ExecForEach("ping -c 1 {{.}}").Stdout()

自定义过滤器

script.Echo("hello world").Filter(func (r io.Reader, w io.Writer) error {
	n, err := io.Copy(w, r)
	fmt.Fprintf(w, "\nfiltered %d bytes\n", n)
	return err
}).Stdout()
// 输出:
// hello world
// filtered 11 bytes

实际用例:统计网站访问频率

package main

import (
	"github.com/bitfield/script"
)

func main() {
	script.Stdin().Column(1).Freq().First(10).Stdout()
}

输入Apache日志文件后的输出示例:

16 176.182.2.191
7 212.205.21.11
1 190.253.121.1
1 90.53.111.17

文档摘要

script提供了丰富的功能,包括:

数据源

  • Args(): 命令行参数
  • Echo(): 字符串
  • File(): 文件内容
  • Stdin(): 标准输入
  • Exec(): 命令输出
  • Get()/Post(): HTTP响应

过滤器

  • Match()/Reject(): 匹配/排除字符串
  • Replace(): 替换文本
  • First()/Last(): 获取前/后N行
  • Column(): 提取列
  • Freq(): 频率统计
  • Concat(): 合并多个文件

输出

  • String(): 作为字符串
  • Bytes(): 作为字节切片
  • Stdout(): 输出到标准输出
  • WriteFile()/AppendFile(): 写入文件

script库起源于《The Power of Go: Tools》一书中的练习,旨在让Go成为编写系统管理工具的强大选择。

最新特性

  • JQ(): 支持JSONLines数据
  • Hash()/HashSums(): 哈希计算
  • WithEnv(): 设置命令环境
  • DecodeBase64()/EncodeBase64(): Base64编解码
  • Tee(): 同时输出到多个目标
  • HTTP支持: Do(), Get(), Post()

script提供了一种简单而强大的方式,用Go编写类似Shell脚本的管道操作,同时保留了Go的类型安全和错误处理优势。


更多关于golang简化DevOps和系统管理任务的Shell脚本编写插件script的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang简化DevOps和系统管理任务的Shell脚本编写插件script的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang的script插件:简化DevOps和系统管理任务

script是一个优秀的Go库,它允许开发者以更优雅的方式编写类似Shell脚本的Go程序,特别适合DevOps和系统管理任务。下面我将详细介绍如何使用这个库。

安装script插件

首先安装这个库:

go get github.com/bitfield/script

基本用法

1. 执行命令并处理输出

package main

import (
	"fmt"
	"github.com/bitfield/script"
)

func main() {
	// 执行ls命令并过滤.go文件
	count, err := script.Exec("ls -l").Match(".go").CountLines()
	if err != nil {
		panic(err)
	}
	fmt.Printf("Found %d Go files\n", count)
}

2. 文件处理

package main

import (
	"fmt"
	"github.com/bitfield/script"
)

func main() {
	// 读取文件并处理内容
	err := script.File("access.log").
		Match("404").
		Column(1).
		Freq().
		First(10).
		Stdout()
	if err != nil {
		panic(err)
	}
}

3. 管道操作

package main

import (
	"github.com/bitfield/script"
)

func main() {
	// 类似Shell管道的操作
	script.Echo("hello world").
		Exec("tr 'a-z' 'A-Z'").
		Stdout()
}

高级功能

1. 并发处理

package main

import (
	"github.com/bitfield/script"
)

func main() {
	// 并发处理文件行
	script.File("largefile.txt").
		Concurrent().
		Match("error").
		Stdout()
}

2. 自定义过滤器

package main

import (
	"github.com/bitfield/script"
	"strings"
)

func main() {
	// 自定义过滤器函数
	toUpper := func(line string) string {
		return strings.ToUpper(line)
	}

	script.Echo("hello script").
		Filter(toUpper).
		Stdout()
}

3. HTTP请求处理

package main

import (
	"fmt"
	"github.com/bitfield/script"
)

func main() {
	// 获取网页内容并处理
	content, err := script.Get("https://example.com").
		Match("a href").
		String()
	if err != nil {
		panic(err)
	}
	fmt.Println(content)
}

实际应用示例

1. 日志分析

package main

import (
	"github.com/bitfield/script"
)

func main() {
	// 分析Nginx日志,找出访问最多的IP
	script.File("/var/log/nginx/access.log").
		Column(1).      // 提取IP地址列
		Freq().         // 计算频率
		First(10).      // 取前10个
		Stdout()        // 输出结果
}

2. 系统监控

package main

import (
	"fmt"
	"github.com/bitfield/script"
	"time"
)

func main() {
	// 监控系统负载
	for {
		load, _ := script.Exec("uptime").
			Column(-1).  // 获取最后一个字段(负载)
			String()
		fmt.Printf("Current load: %s\n", load)
		time.Sleep(5 * time.Second)
	}
}

3. 批量文件处理

package main

import (
	"github.com/bitfield/script"
)

func main() {
	// 批量重命名文件
	script.ListFiles("*.txt").
		FilterScan(func(line string, w io.Writer) {
			newName := strings.Replace(line, ".txt", ".bak", 1)
			fmt.Fprintf(w, "mv %s %s\n", line, newName)
		}).
		ExecForEach()
}

与传统Shell脚本对比的优势

  1. 类型安全:Go是强类型语言,减少运行时错误
  2. 跨平台:编译后的程序可以在任何平台运行
  3. 更好的错误处理:Go的错误处理机制更完善
  4. 性能更好:编译语言通常比解释型脚本执行更快
  5. 可维护性:Go代码比复杂的Shell脚本更易维护
  6. 丰富的标准库:可以轻松集成各种功能

总结

script库为Go开发者提供了类似Shell脚本的编程体验,同时保留了Go的所有优势。它特别适合:

  • 需要比Shell脚本更复杂逻辑的系统管理任务
  • 需要跨平台运行的DevOps工具
  • 需要更好性能和错误处理的任务
  • 需要与现有Go代码集成的脚本

通过这个库,你可以用Go编写出既强大又易于维护的系统管理工具,同时享受Go语言的所有优势。

回到顶部