golang中配置文件*.ini的使用

一、golang中配置文件*.ini的使用

我们在使用golang的使用往往会使用配置文件进行配置项的管理,那么我们该怎样具体操作配置文件呢,先上一段代码。

#先看一下我这个demo的结构,很简单,主要就是读取一下配置文件。
[root@ecs-431f-0001 file]# tree
.
├── cmd
│   ├── main.go
├── conf
│   └── conf.ini
├── docker
│   └── commonAnnotation.war
├── go.mod
├── go.sum
└── utils
    ├── execs
    │   └── exec.go
    └── setting
        └── setting.go

6 directories, 9 files

说一下我这个demo完成的工作:
1、对配置文件的中的配置项进行读取
2、将读取到的配置项读取并且连接到SSH,操作Linux的中命令。

先了解一下ini配置文件

  • INI配置文件有三要素

parameters:指一条配置,就像key = value这样的。

sections:sectionsparameters的集合,sections必须独占一行并且用[]括起来。sections没有明显的结束方式,一个sections的开始就是另一个sections的结束。
comments:指INI配置文件的注释,以 ; 开头。

[ssh] #该名称要和下面mapTo中section名称相对应,必须是[]
HostIp = 117.78.5.222
User = root
Password = Yuantong11
Port = 22
Type=password
package setting

import (
	"gopkg.in/ini.v1"
	"log"
	"runtime"
	"time"
)
//定义全局配置文件*.ini
var cfg *ini.File

//定义结构体
type SSHServer struct {
	HostIp   string
	Port     int
	User     string
	Password string //读
	Type     string
}

var SSHServerSetting = &SSHServer{}

func SetUp() {
	var err error
	//加载配置文件
	cfg, err = ini.Load("../conf/conf.ini")

	if err != nil {
		log.Fatalf("setting.Setup, fail to parse 'app/conf/config.ini': %v", err)
	}
   
	mapTo("ssh", SSHServerSetting)
	fmt.Println("这是init获取到的", SSHServerSetting.HostIp)
}

// mapTo map section
func mapTo(section string, v interface{}) {
	err := cfg.Section(section).MapTo(v)
	if err != nil {
		log.Fatalf("Cfg.MapTo %s err: %v", section, err)
	}
}
func GolangSSh() {
	//1.读取配置文件,获取到这些属性
	sshHost := setting.SSHServerSetting.HostIp
	sshUser := setting.SSHServerSetting.User
	sshPassword := setting.SSHServerSetting.Password
	sshType := setting.SSHServerSetting.Type
	sshPort := setting.SSHServerSetting.Port

	fmt.Println("这是获取到的配置文件中的主机的名称", sshHost)
	//创建sshp登陆配置
	config := &ssh.ClientConfig{
		Timeout:         time.Second, //ssh 连接time out 时间一秒钟, 如果ssh验证错误 会在一秒内返回
		User:            sshUser,
		HostKeyCallback: ssh.InsecureIgnoreHostKey(), //这个可以, 但是不够安全
		//HostKeyCallback: hostKeyCallBackFunc(h.Host),
	}
	if sshType == "password" {
		config.Auth = []ssh.AuthMethod{ssh.Password(sshPassword)}
	}

	//dial 获取ssh client
	addr := fmt.Sprintf("%s:%d", sshHost, sshPort)
	sshClient, err := ssh.Dial("tcp", addr, config)
	if err != nil {
		log.Fatal("创建ssh client 失败", err)
	}
	defer sshClient.Close()

	//创建ssh-session
	session, err := sshClient.NewSession()
	if err != nil {
		log.Fatal("创建ssh session 失败", err)
	}
	defer session.Close()
	//执行远程命令(需要注意的是通过;分隔命令,不能使用&&)
	combo, err := session.CombinedOutput(" cd /; ls -al")
	if err != nil {
		log.Fatal("远程执行cmd 失败", err)
	}
	log.Println("命令输出:", string(combo))
}
package main
func init() {
	setting.SetUp()
}

func main(){
//调用登录ssh的函数
GolangSSh()
}

查看结果

[root@ecs-431f-0001 cmd]# go run main.go 
这是init获取到的 117.78.5.222
这是获取到的配置文件中的主机的名称 117.78.5.222
2021/09/17 17:19:54 命令输出: total 128
dr-xr-xr-x.  29 root root  4096 Sep 14 09:47 .
dr-xr-xr-x.  29 root root  4096 Sep 14 09:47 ..
-rw-r--r--    1 root root     0 Dec 12  2020 .autorelabel
lrwxrwxrwx    1 root root     7 Nov  3  2020 bin -> usr/bin
dr-xr-xr-x.   5 root root  4096 Mar  5  2021 boot
drwxr-xr-x    7 root root  4096 Dec 12  2020 CloudResetPwdUpdateAgent
drwxr-xr-x    7 root root  4096 Dec 12  2020 CloudrResetPwdAgent
drwxr-xr-x    9 root root  4096 Jul  4 11:45 cust2
drwxr-xr-x   19 root root  2960 Aug 21 18:41 dev
drwxr-xr-x    3 root root  4096 Jul  8 09:19 docker
drwxr-xr-x.  93 root root  4096 Sep  1 09:42 etc
drwxr-xr-x.   2 root root  4096 Nov  3  2020 home
lrwxrwxrwx    1 root root     7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx    1 root root     9 Nov  3  2020 lib64 -> usr/lib64
drwx------.   2 root root 16384 Dec 12  2020 lost+found
drwxr-xr-x.   2 root root  4096 Nov  3  2020 media
drwxr-xr-x.   2 root root  4096 Nov  3  2020 mnt
drwxr-xr-x    3 root root  4096 Jun  5 13:44 mydata
drwxr-xr-x    3 root root  4096 Aug  2 18:24 nfsdata
-rw-r--r--    1 root root  5500 Sep 14 09:45 nginx.conf
drwxrwxrwx    2 root root  4096 Sep 15 20:33 nginxvolume
drwxr-xr-x.  11 root root  4096 Aug 27 13:07 opt
drwxr-xr-x    3 root root  4096 Aug 18 13:24 path
dr-xr-xr-x  219 root root     0 Aug 21 18:41 proc
drwxr-xr-x    4 root root  4096 May  9 12:42 qcwork
dr-xr-x---.  11 root root  4096 Sep 17 14:23 root
drwxr-xr-x   28 root root   940 Aug 31 09:27 run
lrwxrwxrwx    1 root root     8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x    3 root root  4096 Jul 20 17:49 src
drwxr-xr-x.   2 root root  4096 Nov  3  2020 srv
dr-xr-xr-x   13 root root     0 Aug 21 18:41 sys
drwxr-xr-x    4 root root  4096 Sep 15 09:19 test
drwxrwxrwt. 175 root root 12288 Sep 17 17:19 tmp
drwxr-xr-x.  13 root root  4096 Mar  3  2021 usr
drwxr-xr-x.  20 root root  4096 Mar  5  2021 var

源码分析:读取配置的过程

//这个函数其实就是将sections和struct对应起来,可以对应多个
mapTo("ssh", SSHServerSetting)
// mapTo map section
func mapTo(section string, v interface{}) {
	err := cfg.Section(section).MapTo(v)
	if err != nil {
		log.Fatalf("Cfg.MapTo %s err: %v", section, err)
	}
}
//首先将传过来的参数ssh,去配置文件中寻找
func (f *File) Section(name string) *Section {
	sec, err := f.GetSection(name) //找到就返回
	if err != nil {
		// Note: It's OK here because the only possible error is empty section name,
		// but if it's empty, this piece of code won't be executed.
		sec, _ = f.NewSection(name) //没有找到就创建一个
		return sec
	}
	return sec
}
//通过传递过来的参数进行创建
func (f *File) NewSection(name string) (*Section, error) {
	if len(name) == 0 {
		return nil, errors.New("empty section name")
	}

	if (f.options.Insensitive || f.options.InsensitiveSections) && name != DefaultSection {
		name = strings.ToLower(name)
	}

	if f.BlockMode {
		f.lock.Lock()
		defer f.lock.Unlock()
	}

	if !f.options.AllowNonUniqueSections && inSlice(name, f.sectionList) {
		return f.sections[name][0], nil
	}

	f.sectionList = append(f.sectionList, name)

	// NOTE: Append to indexes must happen before appending to sections,
	// otherwise index will have off-by-one problem.
	f.sectionIndexes = append(f.sectionIndexes, len(f.sections[name]))

	sec := newSection(f, name)
	f.sections[name] = append(f.sections[name], sec)

	return sec, nil
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值