• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

go监视文件改变实现同步--包含遍历文件夹,执行cmd命令,检测文件改变 ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
package main

import (
	"fmt"
	"time"

	"os/exec"

	"strings"

	"io/ioutil"

	"os"

	"github.com/howeyc/fsnotify"

	"sync"
)

const (
	filePath   = "/home/ubuntu/GzhuOJ/public"
	hostname   = "[email protected]"
	remotePath = "/home/public"
)

var watcher *fsnotify.Watcher
var mutex sync.Mutex

func Print(args ...interface{}) {
	fmt.Println(time.Now(), args)
}
func isDir(path string) bool {
	fileInfo, err := os.Stat(path)
	if err != nil {
		Print("error:", err.Error())
		return false
	}
	return fileInfo.IsDir()
}
func watchPath(filePath string) {
	Print("watchPath:", filePath)
	err := watcher.Watch(filePath)
	if err != nil {
		Print(err.Error())
		return
	}
}
func broweDir(path string) {
	Print("broweDir:", path)
	dir, err := os.Open(path)
	if err != nil {
		Print("error:", err.Error())
		return
	}
	defer dir.Close()
	names, err := dir.Readdirnames(-1)
	if err != nil {
		Print("error:", err.Error())
		return
	}
	for _, name := range names {
		dirPath := path + "/" + name
		if !isDir(dirPath) {
			continue
		}
		watchPath(dirPath)
		broweDir(dirPath)
	}
}

func main() {
	var err error
	watcher, err = fsnotify.NewWatcher()
	if err != nil {
		panic(err)
	}
	defer watcher.Close()
	broweDir(filePath)
	watchPath(filePath)
	dealWatch()
}
func copy(event *fsnotify.FileEvent) *exec.Cmd {
	return exec.Command(
		"scp",
		"-r",
		"-P 23456",
		event.Name,
		hostname+":"+remotePath+strings.TrimPrefix(event.Name, filePath))
}
func remove(event *fsnotify.FileEvent) *exec.Cmd {
	return exec.Command(
		"ssh",
		"-p 23456",
		hostname,
		`rm -r `+remotePath+strings.TrimPrefix(event.Name, filePath)+``)
}
func dealWatch() {
	for {
		func() {
			//mutex.Lock()
			//defer mutex.Unlock()
			select {
			case event := <-watcher.Event:
					Print("event: ", event)
					var cmd *exec.Cmd
					if event.IsCreate() || event.IsModify() {
						cmd = copy(event)
					}
					if event.IsDelete() || event.IsRename() {
						cmd = remove(event)
					}
					Print("cmd:", cmd.Args)
					stderr, err := cmd.StderrPipe()
					if err != nil {
						Print(err.Error())
						return
					}
					defer stderr.Close()
					stdout, err := cmd.StdoutPipe()
					if err != nil {
						Print(err.Error())
						return
					}
					defer stdout.Close()
					if err = cmd.Start(); err != nil {
						Print(err.Error())
						return
					}
					errBytes, err := ioutil.ReadAll(stderr)
					if err != nil {
						Print(err.Error())
						return
					}
					outBytes, err := ioutil.ReadAll(stdout)
					if err != nil {
						Print(err.Error())
						return
					}
					if len(errBytes) != 0 {
						Print("errors:", string(errBytes))
					}
					if len(outBytes) != 0 {
						Print("output:", string(outBytes))
					}
					if err = cmd.Wait(); err != nil {
						Print(err.Error())
					}
			case err := <-watcher.Error:
				Print("error: ", err.Error())
			}
		}()
	}
}

 

go cmd 的命令里不能ssh user@ip "rm /home/public" 最后的参数”/home/public"不要写引号("),不然会执行命令失败,但命令行里不加引号可以执行,所以尽量不要加引号

 

要注意的是一个fsnotify.Watcher能watch多个文件和文件夹,不要一个Watcher watch一个文件夹或文件,太多会报Too many open files


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go标准库的学习-encoding/xml发布时间:2022-07-10
下一篇:
[摘]Go语言简介(下)—特性发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap