背景:通过go写的程序调用dos命令(如dir c:),返回值往往有中文,默认会出现乱码。

解决:转码。

代码:GO

package shellLib

import (
"golang.org/x/text/encoding/simplifiedchinese"
) type Charset string const (
UTF8 = Charset("UTF-8")
GB18030 = Charset("GB18030")
) //解决执行bat文件时返回的内容是乱码
func ConvertByte2String(byte []byte, charset Charset) string {
var str string
switch charset {
case GB18030:
decodeBytes, _ := simplifiedchinese.GB18030.NewDecoder().Bytes(byte)
str = string(decodeBytes)
case UTF8:
fallthrough
default:
str = string(byte)
} return str
}

调用代码:

func ExecuteByFile(title string,exitChan chan string,cmdInput,shFileName,osName string) (cmdResult string) {
defer func() {
if p := recover(); p != nil {
fmt.Printf("出错了: %v", p)
debug.PrintStack()
}
//统一在退出前关闭心跳
setChan(title,exitChan,cmdResult)
}() if strings.TrimSpace(cmdInput)==""{
log.Println("脚本为空,程序中止")
return "#ERROR#:脚本为空,程序中止。"
}
//time.Sleep(3*time.Second)//模拟长时间执行
//重要思路:不要执行命令,而是将命令+参数写到脚本文件(bat,sh)中,然后简单执行文件即可。
ScriptToShell(shFileName,osName,cmdInput)
//转为执行shell脚本
cmdInput = shFileName
var sb bytes.Buffer
if osName=="windows"{
cmd := exec.Command("cmd.exe", "/C", shFileName)
cmd.Stdout = &sb
err := cmd.Run()
if err != nil {
cmdResult = fmt.Sprintf("#ERROR#%s(请在dos下直接运行【%s】来查错)",err.Error(),shFileName)
log.Printf("#ERROR#%s",cmdResult)
return
}
cmdResult = ConvertByte2String(sb.Bytes(), GB18030)
return
}
//在linux平台下执行脚本文件
command := "/bin/bash"
params := []string{"-c", cmdInput}
var contentArray = make([]string, 0, 5)
contentArray = contentArray[0:0]
cmd := exec.Command(command, params...)
//获取标准输出:要点1
sbStdErr := bytes.NewBuffer(nil)
cmd.Stderr = sbStdErr
//实时获取:要点1:需要使用 Cmd 结构的 StdoutPipe() 方法创建一个管道连接到命令执行的输出
stdout, err := cmd.StdoutPipe()
if err != nil {
fmt.Fprintln(os.Stderr, "error=>", err.Error())
return err.Error()
} var index int
cmd.Start() // Start开始执行c包含的命令,但并不会等待该命令完成即返回。Wait方法会返回命令的返回状态码并在命令返回后释放相关的资源。
readerStdOut := bufio.NewReader(stdout)
//要点2:然后用 for 循环从管道中实时读取命令执行的输出并打印到终端
//实时循环读取输出流中的一行内容
for {
line, err2 := readerStdOut.ReadString('\n')
if err2 != nil || io.EOF == err2 {
//log.Printf("error:%v\n",err2.Error())
//获取标准输出:要点2
errMsg := string(sbStdErr.Bytes())
errMsg = strings.TrimSpace(errMsg)
if errMsg!=""{
sb.WriteString(errMsg)
fmt.Printf("#error:%s\n", errMsg)
}
break
}else{
sb.WriteString(line+"\n")
}
fmt.Printf("日志:【%s】\n",strings.TrimSpace(line))
index++
contentArray = append(contentArray, line)
}
//重要说明:不要用Wait,找了好久啊。。。
//cmd.Wait()
//往通道中存入一个值以结束心跳
cmdResult = sb.String()
cmdResult = strings.TrimSpace(cmdResult)
//不能在defer中设置,defer编译时cmdResult还是空的,只是在return前执行
//setChan(title,exitChan,cmdResult)
return
}

主方法:

func ExecuteCmd(loginId,mapType,tcpUrl,title,cmdStr,scriptFile string,heartSec int)(result string)  {
log.Println("ExecuteCmd.tcpURL:%s\n",tcpUrl)
sysMap[loginId] = mapType
//执行前清空已有的日志缓存
//sbLog.Reset()
//默认每5秒提供一次心跳
exitChan := make(chan string)
//在内部判断_双引号替换符存在且不为空时,会将指定的符号替换为双引号。执行完以后会清空“_双引号替换符”的值。
cmdStr = strings.ReplaceAll(cmdStr,"`",`"`)
//获取文件名
osName := osMap[loginId]
//如果为空,则根据loginId自己拼接,不为空则使用指定路径
if scriptFile==""{
scriptFile = fmt.Sprintf("%s/%s",fileLib.CurrDir(),loginId)
if strings.Contains(osName,"win"){
scriptFile = fmt.Sprintf("%s.bat",scriptFile)
}else{
scriptFile = fmt.Sprintf("%s.sh",scriptFile)
}
}
go PrintHeart(loginId,mapType,tcpUrl,title,exitChan, MainParam.LogPushFile,heartSec)
result = shellLib.ExecuteByFile(title,exitChan,cmdStr,scriptFile,osName)
//下面的函数是等待信号的程序,会一直阻塞,直到解除(所以这个方法不要用go)
return result
}

通过go调用bat解决乱码核心代码的更多相关文章

  1. 解决JSP调用JavaBean出现乱码问题

    解决JSP调用JavaBean出现乱码问题 话不多说放代码 144 Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style D ...

  2. 【五子棋AI循序渐进】关于VCT,VCF的思考和核心代码

    前面几篇发布了一些有关五子棋的基本算法,其中有一些BUG也有很多值得再次思考的问题,在框架和效果上基本达到了一个简单的AI的水平,当然,我也是初学并没有掌握太多的高级技术.对于这个程序现在还在优化当中 ...

  3. 为sublime安装package control 解决乱码问题 Mac版

    为sublime安装package control   Mac版参考 https://sublime.wbond.net/installation 防止中文乱码其实只需要2个东东  一个GBK enc ...

  4. 利用WxJava实现网站集成微信登录功能,核心代码竟然不超过10行

    最近网站PC端集成微信扫码登录,踩了不少坑,在此记录下实现过程和注意事项. 本文目录 一.微信开放平台操作步骤1.创建“网站应用”2.获取AppID和AppSecret二.开发指南三.开发实战1.po ...

  5. c++ 使用 gsoap 调用 WebService 中文乱码

    c++ 使用 gsoap 调用  WebService 中文乱码   问题产生: 使用gsoap时,如果WebService服务端及客户调用端都使用 C++ , 再传递中文时不会存在乱码问题, 当客户 ...

  6. Windows上Tomcat安装以及解决乱码问题

    Windows上Tomcat安装以及解决乱码问题 下载tomcat8 1.进入tomcat官网 官方网站 2.选择windows的版本 解压 确定自己配置好了jdk jdk的相关配置 配置好tomca ...

  7. Entity Framework 6 Recipes 2nd Edition(12-1)译 -> 当SaveChanges( ) 被调用时执行你的代码

    第12章定制EF 在本章的小节里,定制实体对象和EF处理的一些功能.这些小节将涵盖很多”幕后”的事情,能让你的代码更加统一解决一些事情,比如用一个业务规则中心统一地为实体执行验证. 本章开始的小节,将 ...

  8. SpringMVC解决乱码

    SpringMVC解决乱码 在web.xml中配置如下代码

  9. 上传Text文档并转换为PDF(解决乱码)

    前些日子,Insus.NET有分享一篇<上传Text文档并转换为PDF>http://www.cnblogs.com/insus/p/4313092.html 它是按最简单与默认方式来处理 ...

随机推荐

  1. [NOI2020] 制作菜品

    看懂题目是生产第一要素. 考虑\(m = n - 1\)则必定有解.我们每次选择最小的和最大的拼在一起即可. 当\(m\)大于\(n\),那么我们只要每次选择最大的给他消掉即可. \(m = n - ...

  2. ABC201题解

    因为学校的某些操作. 让最近两天的\(Atcoder\)都能打了,挺开心的. 想上次\(ABC\)看错题意,失败退场. ------------------------------ \(A\) 直接手 ...

  3. 【R方差分析】蛋白质表达量多组比较

    初始数据类似: 蛋白质组数据虽不是严格的正态分布,但目前最常用的检验方法还是T检验(两组比较)和方差分析(多组比较).这个话题值得深究,这里不展开. 主要是求多个蛋白的Pvalue值或FDR,用于差异 ...

  4. CPU大小端模式及转换

    通信协议中的数据传输.数组的存储方式.数据的强制转换等这些都会牵涉到大小端问题. CPU的大端和小端模式很多地方都会用到,但还是有许多朋友不知道,今天暂且普及一下. 一.为什么会有大小端模式之分呢? ...

  5. MYSQL(3)

    加载C盘下的目录 全表查询 查询部分字段 查询总数 条件过滤 and or 包含 范围检查 between and 否定结果not 匹配任意字符    like 以什么开始^   rlike 以什么结 ...

  6. javaWeb - 2 — ajax、json — 最后附:后台获取前端中的input type = "file"中的信息 — 更新完毕

    1.ajax是什么? 面向百度百科一下就知道了,这里就简单提炼一下 Ajax即Asynchronous Javascript And XML(异步JavaScript和XML).当然其实我们学的应该叫 ...

  7. 零基础学习java------39---------json格式交互,Restful(不懂),静态资源映射,SSM整合(ssm整合思想,application.xml文件详解(声明式事务管理),)

    一. json格式交互(知道) 1 . 回顾ajax基本语法 $.ajax({ url:"", // 请求的后台路径 data:{"":"" ...

  8. Linux—禁止用户SSH登录方法总结

    Linux-禁止用户SSH登录方法总结 一.禁止用户登录 1.修改用户配置文件/etc/shadow       将第二栏设置为"*",如下.那么该用户就无法登录.但是使用这种方式 ...

  9. Linux学习 - 文件包处理命令

    一.搜索文件find find  [搜索范围]  [匹配条件] (1) -name(名字查找) <1>  find  /etc  -name  init 查找/etc下以 "in ...

  10. zabbix之主动模式和proxy的主动模式

    #:找一台新主机配置上agent,注意版本要和server端保持一样 #:官网地址:https://www.zabbix.com/documentation/4.0/zh/manual/install ...