背景:通过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. [源码解析] PyTorch 分布式 Autograd (4) ---- 如何切入引擎

    [源码解析] PyTorch 分布式 Autograd (4) ---- 如何切入引擎 目录 [源码解析] PyTorch 分布式 Autograd (4) ---- 如何切入引擎 0x00 摘要 0 ...

  2. Linux图片查看软件ImageMagick安装

    在Linux中查看图片,这个需求是非常常见的.总不至于在集群中生成个图片,随便看下效果,也要用filezilla.winscp之类的远程文件传输工具导过来导过去吧,这样效率太低. Linux图片查看常 ...

  3. 解决sourceforge下载文件慢的方法

    Sourceforge是一些开源软件经常用到的网站,然而国内的网站一直不稳定,如今是可以访问,但是一直无法下载,或者是下载速度慢,导致下载中断 镜像源:http://sourceforge.mirro ...

  4. R语言因子排序

    画图的时候,排序是个很重要的技巧,比如有时候会看下基因组每条染色体上的SNP的标记数量,这个时候直接做条形图是一种比较直观的方法,下面我们结合实际例子来看下: 在R环境下之际构建一个数据框,一列染色体 ...

  5. 16-4SUM

    4.30更新,已经AC 18. 4Sum My Submissions QuestionEditorial Solution Total Accepted: 71102 Total Submissio ...

  6. 开发安卓记账本-HelloAndroid的完成

    这个寒假要完成一个家庭记账本软件的开发,今天完成了Android Studio的安装与第一个安卓应用的运行(HelloAndroid) 下图是效果: 1.Android Studio的安装 可直接百度 ...

  7. 日常Java 2021/10/25

    ArrayList存储数字 import java.util.ArrayList; public class Arr_test { public static void main(String[] a ...

  8. Docker学习(六)——Dockerfile文件详解

    Docker学习(六)--Dockerfile文件详解 一.环境介绍 1.Dockerfile中所用的所有文件一定要和Dockerfile文件在同一级父目录下,可以为Dockerfile父目录的子目录 ...

  9. SpringIOC原理浅析

    1. IoC理论的背景我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 图1:软件系统中耦合的对象 如果我们打开机械 ...

  10. VFL

    VFL 1. 概念 VFL全称是Visual Format Language,翻译过来是"可视化格式语言" VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言 2. ...