背景:通过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. AGC050B Three Coins

    做的时候有思考到是否能转化成移动点问题,但是没有清晰的把他解释出来. NOIP的时候也一样,T3也有考虑到是否能转为差分,但是也没有清晰的写出来. 自己做题的时候应尽量保证草稿纸和思绪的清晰,而不是在 ...

  2. CF1610F F. Mashtali: a Space Oddysey

    我们首先发现有如下性质: 我们不妨先随机定向边,那么我们发现无论我们如何翻转边. 都会对其两端的点,造成 \(2 / 4\) 的影响,所以我们发现如果一个点其和他相连的所有边权和为偶数,则我们不能调整 ...

  3. [ARC 122]

    最近状态差到爆炸. \(AT\)连掉两把分,啥时候能上黄啊. \(A\) 考虑直接动归. 把\(O(n^2)\)的动归后缀和优化成\(O(n)\) A #include<iostream> ...

  4. R包xlsx安装与使用

     1. Rstudio安装xlsx报错 xlsx包加载依赖Java环境,我之前就安装过Java,但安装xlsx成功后,加载xlsx时一直报错: Error : loadNamespace()里算'rJ ...

  5. python-django-ORM模型

    ORM模型: Object Relational Mapping 对象关系映射 配置引擎的时候最好直接复制: DATABASES = { 'default': { 'ENGINE': 'django. ...

  6. 毕业设计压力测试——jmeter

    ------------恢复内容开始------------ JMeter是一款纯java编写负载功能测试和性能测试开源工具软件.相比Loadrunner而言,JMeter小巧轻便且免费,逐渐成为了主 ...

  7. 打造基于 PostgreSQL/openGauss 的分布式数据库解决方案

    在 MySQL ShardingSphere-Proxy 逐渐成熟并被广泛采用的同时,ShardingSphere 团队也在 PostgreSQL ShardingSphere-Proxy 上持续发力 ...

  8. Idea中JSP页面中out内置对象报错out.println标红问题

    问题如图: 解决方法: 导入jar包 1.在pom.xml的<dependencies>里面复制 <dependency> <groupId>javax.servl ...

  9. 为什么CTR预估使用AUC来评估模型?

    ctr预估简单的解释就是预测用户的点击item的概率.为什么一个回归的问题需要使用分类的方法来评估,这真是一个好问题,尝试从下面几个关键问题去回答. 1.ctr预估是特殊的回归问题 ctr预估的目标函 ...

  10. AI ubantu 环境安装

    ubantu安装记录 apt install python3-pip anaconda安装 https://repo.anaconda.com/archive/Anaconda3-2020.11-Li ...