init
commit
bcc27ff52f
@ -0,0 +1,134 @@
|
||||
package starssh
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/pkg/sftp"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func SftpTransferOut(localFilePath, remotePath string, sftpClient *sftp.Client) error {
|
||||
srcFile, err := os.Open(localFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer srcFile.Close()
|
||||
// var remoteFileName = filepath.Base(localFilePath)
|
||||
dstFile, err := sftpClient.Create(remotePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dstFile.Close()
|
||||
for {
|
||||
buf := make([]byte, 1024)
|
||||
n, err := srcFile.Read(buf)
|
||||
dstFile.Write(buf[:n])
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func SftpTransferOutByte(localData []byte, remotePath string, sftpClient *sftp.Client) error {
|
||||
dstFile, err := sftpClient.Create(remotePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dstFile.Close()
|
||||
_, err = dstFile.Write(localData)
|
||||
return err
|
||||
}
|
||||
|
||||
func SftpTransferOutFunc(localFilePath, remotePath string, bufcap int, rtefunc func(float64), sftpClient *sftp.Client) error {
|
||||
num := 0
|
||||
srcFile, err := os.Open(localFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer srcFile.Close()
|
||||
stat, _ := os.Stat(localFilePath)
|
||||
filebig := float64(stat.Size())
|
||||
//var remoteFileName = filepath.Base(localFilePath)
|
||||
dstFile, err := sftpClient.Create(remotePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dstFile.Close()
|
||||
for {
|
||||
buf := make([]byte, bufcap)
|
||||
n, err := srcFile.Read(buf)
|
||||
num += n
|
||||
go rtefunc(float64(num) / filebig * 100)
|
||||
dstFile.Write(buf[:n])
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func SftpTransferInByte(remotePath string, sftpClient *sftp.Client) ([]byte, error) {
|
||||
dstFile, err := sftpClient.Open(remotePath)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
defer dstFile.Close()
|
||||
buf := new(bytes.Buffer)
|
||||
_, err = dstFile.WriteTo(buf)
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
|
||||
func SftpTransferIn(src, dst string, sftpClient *sftp.Client) error {
|
||||
srcFile, err := sftpClient.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer srcFile.Close()
|
||||
//var localFileName = filepath.Base(src)
|
||||
dstFile, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dstFile.Close()
|
||||
|
||||
if _, err = srcFile.WriteTo(dstFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SftpTransferInFunc(src, dst string, bufcap int, rtefunc func(float64), sftpClient *sftp.Client) error {
|
||||
num := 0
|
||||
srcFile, err := sftpClient.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer srcFile.Close()
|
||||
stat, _ := srcFile.Stat()
|
||||
filebig := float64(stat.Size())
|
||||
//var localFileName = filepath.Base(src)
|
||||
dstFile, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dstFile.Close()
|
||||
for {
|
||||
buf := make([]byte, bufcap)
|
||||
n, err := srcFile.Read(buf)
|
||||
num += n
|
||||
go rtefunc(float64(num) / filebig * 100)
|
||||
dstFile.Write(buf[:n])
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -0,0 +1,636 @@
|
||||
package starssh
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type StarSSH struct {
|
||||
Client *ssh.Client
|
||||
PublicKey ssh.PublicKey
|
||||
PubkeyBase64 string
|
||||
Hostname string
|
||||
RemoteAddr net.Addr
|
||||
Banner string
|
||||
LoginInfo LoginInput
|
||||
online bool
|
||||
}
|
||||
|
||||
type LoginInput struct {
|
||||
KeyExchanges []string
|
||||
Ciphers []string
|
||||
MACs []string
|
||||
User string
|
||||
Password string
|
||||
Prikey string
|
||||
PrikeyPwd string
|
||||
Addr string
|
||||
Port int
|
||||
Timeout time.Duration
|
||||
HostKeyCallback func(string, net.Addr, ssh.PublicKey) error
|
||||
BannerCallback func(string) error
|
||||
}
|
||||
type StarShell struct {
|
||||
Keyword string
|
||||
UseWaitDefault bool
|
||||
Session *ssh.Session
|
||||
in io.Writer
|
||||
out *bufio.Reader
|
||||
er *bufio.Reader
|
||||
outbyte []byte
|
||||
errbyte []byte
|
||||
lastout int64
|
||||
errors error
|
||||
isprint bool
|
||||
isfuncs bool
|
||||
iscolor bool
|
||||
isecho bool
|
||||
rw sync.RWMutex
|
||||
funcs func(string)
|
||||
}
|
||||
|
||||
func Login(info LoginInput) (*StarSSH, error) {
|
||||
var (
|
||||
auth []ssh.AuthMethod
|
||||
clientConfig *ssh.ClientConfig
|
||||
config ssh.Config
|
||||
err error
|
||||
)
|
||||
sshInfo := new(StarSSH)
|
||||
// get auth method
|
||||
auth = make([]ssh.AuthMethod, 0)
|
||||
if info.Prikey == "" {
|
||||
keyboardInteractiveChallenge := func(
|
||||
user,
|
||||
instruction string,
|
||||
questions []string,
|
||||
echos []bool,
|
||||
) (answers []string, err error) {
|
||||
if len(questions) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
return []string{info.Password}, nil
|
||||
}
|
||||
auth = append(auth, ssh.Password(info.Password))
|
||||
auth = append(auth, ssh.KeyboardInteractive(keyboardInteractiveChallenge))
|
||||
} else {
|
||||
pemBytes := []byte(info.Prikey)
|
||||
var signer ssh.Signer
|
||||
if info.PrikeyPwd == "" {
|
||||
signer, err = ssh.ParsePrivateKey(pemBytes)
|
||||
} else {
|
||||
signer, err = ssh.ParsePrivateKeyWithPassphrase(pemBytes, []byte(info.PrikeyPwd))
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
auth = append(auth, ssh.PublicKeys(signer))
|
||||
}
|
||||
|
||||
if len(info.Ciphers) == 0 {
|
||||
config = ssh.Config{
|
||||
Ciphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc", "chacha20-poly1305@openssh.com"},
|
||||
}
|
||||
} else {
|
||||
config = ssh.Config{
|
||||
Ciphers: info.Ciphers,
|
||||
}
|
||||
}
|
||||
|
||||
if len(info.MACs) != 0 {
|
||||
config.MACs = info.MACs
|
||||
}
|
||||
if len(info.KeyExchanges) != 0 {
|
||||
config.KeyExchanges = info.KeyExchanges
|
||||
}
|
||||
|
||||
if info.Timeout == 0 {
|
||||
info.Timeout = time.Second * 5
|
||||
}
|
||||
hostKeycbfunc := func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||
|
||||
sshInfo.PublicKey = key
|
||||
sshInfo.RemoteAddr = remote
|
||||
sshInfo.Hostname = hostname
|
||||
if info.HostKeyCallback != nil {
|
||||
return info.HostKeyCallback(hostname, remote, key)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
bannercbfunc := func(banner string) error {
|
||||
sshInfo.Banner = banner
|
||||
if info.BannerCallback != nil {
|
||||
return info.BannerCallback(banner)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
clientConfig = &ssh.ClientConfig{
|
||||
User: info.User,
|
||||
Auth: auth,
|
||||
Timeout: info.Timeout,
|
||||
Config: config,
|
||||
HostKeyCallback: hostKeycbfunc,
|
||||
BannerCallback: bannercbfunc,
|
||||
}
|
||||
|
||||
// connet to ssh
|
||||
|
||||
sshInfo.LoginInfo = info
|
||||
sshInfo.Client, err = ssh.Dial("tcp", fmt.Sprintf("%s:%d", info.Addr, info.Port), clientConfig)
|
||||
if err == nil && sshInfo.PublicKey != nil {
|
||||
sshInfo.online = true
|
||||
sshInfo.PubkeyBase64 = base64.StdEncoding.EncodeToString(sshInfo.PublicKey.Marshal())
|
||||
}
|
||||
return sshInfo, err
|
||||
}
|
||||
|
||||
func LoginSimple(host string, user string, passwd string, prikeyPath string, port int, timeout time.Duration) (*StarSSH, error) {
|
||||
var info = LoginInput{
|
||||
Addr: host,
|
||||
Port: port,
|
||||
Timeout: timeout,
|
||||
User: user,
|
||||
}
|
||||
if prikeyPath != "" {
|
||||
prikey, err := ioutil.ReadFile(prikeyPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info.Prikey = string(prikey)
|
||||
if passwd != "" {
|
||||
info.PrikeyPwd = passwd
|
||||
}
|
||||
} else {
|
||||
info.Password = passwd
|
||||
}
|
||||
return Login(info)
|
||||
}
|
||||
|
||||
func (this *StarShell) ShellWait(cmd string) (string, string, error) {
|
||||
var outc, errc string = " ", " "
|
||||
this.Clear()
|
||||
defer this.Clear()
|
||||
echo := "echo b7Y85R56TUY6R5UTb612"
|
||||
err := this.WriteCommand(cmd)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
time.Sleep(time.Millisecond * 20)
|
||||
err = this.WriteCommand(echo)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
for {
|
||||
time.Sleep(time.Millisecond * 120)
|
||||
outs := string(this.outbyte)
|
||||
errs := string(this.errbyte)
|
||||
outs = strings.TrimSpace(strings.ReplaceAll(outs, "\r\n", "\n"))
|
||||
errs = strings.TrimSpace(strings.ReplaceAll(errs, "\r\n", "\n"))
|
||||
if len(outs) >= len(cmd+"\n"+echo) && outs[0:len(cmd+"\n"+echo)] == cmd+"\n"+echo {
|
||||
outs = outs[len(cmd+"\n"+echo):]
|
||||
} else if len(outs) >= len(cmd) && outs[0:len(cmd)] == cmd {
|
||||
outs = outs[len(cmd):]
|
||||
}
|
||||
if len(errs) >= len(cmd) && errs[0:len(cmd)] == cmd {
|
||||
errs = errs[len(cmd):]
|
||||
}
|
||||
if this.UseWaitDefault {
|
||||
if strings.Index(string(outs), "b7Y85R56TUY6R5UTb612") >= 0 {
|
||||
list := strings.Split(string(outs), "\n")
|
||||
for _, v := range list {
|
||||
if strings.Index(v, "b7Y85R56TUY6R5UTb612") < 0 {
|
||||
outc += v + "\n"
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
if strings.Index(string(errs), "b7Y85R56TUY6R5UTb612") >= 0 {
|
||||
list := strings.Split(string(errs), "\n")
|
||||
for _, v := range list {
|
||||
if strings.Index(v, "b7Y85R56TUY6R5UTb612") < 0 {
|
||||
errc += v + "\n"
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if this.Keyword != "" {
|
||||
if strings.Index(string(outs), this.Keyword) >= 0 {
|
||||
list := strings.Split(string(outs), "\n")
|
||||
for _, v := range list {
|
||||
if strings.Index(v, this.Keyword) < 0 && strings.Index(v, "b7Y85R56TUY6R5UTb612") < 0 {
|
||||
outc += v + "\n"
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
if strings.Index(string(errs), this.Keyword) >= 0 {
|
||||
list := strings.Split(string(errs), "\n")
|
||||
for _, v := range list {
|
||||
if strings.Index(v, this.Keyword) < 0 && strings.Index(v, "b7Y85R56TUY6R5UTb612") < 0 {
|
||||
errc += v + "\n"
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.TrimColor(strings.TrimSpace(outc)), this.TrimColor(strings.TrimSpace(errc)), err
|
||||
}
|
||||
|
||||
func (this *StarShell) Close() error {
|
||||
return this.Session.Close()
|
||||
}
|
||||
|
||||
func (this *StarShell) SwitchNoColor(is bool) {
|
||||
this.iscolor = is
|
||||
}
|
||||
|
||||
func (this *StarShell) SwitchEcho(is bool) {
|
||||
this.isecho = is
|
||||
}
|
||||
|
||||
func (this *StarShell) TrimColor(str string) string {
|
||||
if this.iscolor {
|
||||
return SedColor(str)
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
/*
|
||||
本函数控制是否在本地屏幕上打印远程Shell的输出内容[true|false]
|
||||
*/
|
||||
func (this *StarShell) SwitchPrint(run bool) {
|
||||
this.isprint = run
|
||||
}
|
||||
|
||||
/*
|
||||
本函数控制是否立即处理远程Shell输出每一行内容[true|false]
|
||||
*/
|
||||
func (this *StarShell) SwitchFunc(run bool) {
|
||||
this.isfuncs = run
|
||||
}
|
||||
|
||||
func (this *StarShell) SetFunc(funcs func(string)) {
|
||||
this.funcs = funcs
|
||||
}
|
||||
|
||||
func (this *StarShell) Clear() {
|
||||
defer this.rw.Unlock()
|
||||
this.rw.Lock()
|
||||
this.outbyte = []byte{}
|
||||
this.errbyte = []byte{}
|
||||
time.Sleep(time.Millisecond * 15)
|
||||
}
|
||||
|
||||
func (this *StarShell) ShellClear(cmd string, sleep int) (string, string, error) {
|
||||
defer this.Clear()
|
||||
this.Clear()
|
||||
return this.Shell(cmd, sleep)
|
||||
}
|
||||
|
||||
func (this *StarShell) Shell(cmd string, sleep int) (string, string, error) {
|
||||
if err := this.WriteCommand(cmd); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
tmp1, tmp2, err := this.GetResult(sleep)
|
||||
tmps := this.TrimColor(strings.TrimSpace(string(tmp1)))
|
||||
if this.isecho {
|
||||
n := len(strings.Split(cmd, "\n"))
|
||||
if n == 1 {
|
||||
list := strings.SplitN(tmps, "\n", 2)
|
||||
if len(list) == 2 {
|
||||
tmps = list[1]
|
||||
}
|
||||
} else {
|
||||
list := strings.Split(tmps, "\n")
|
||||
cmds := strings.Split(cmd, "\n")
|
||||
for _, v := range cmds {
|
||||
for k, v2 := range list {
|
||||
if strings.TrimSpace(v2) == strings.TrimSpace(v) {
|
||||
list[k] = ""
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
tmps = ""
|
||||
for _, v := range list {
|
||||
if v != "" {
|
||||
tmps += v + "\n"
|
||||
}
|
||||
}
|
||||
tmps = tmps[0 : len(tmps)-1]
|
||||
}
|
||||
}
|
||||
return tmps, this.TrimColor(strings.TrimSpace(string(tmp2))), err
|
||||
}
|
||||
|
||||
func (this *StarShell) GetResult(sleep int) ([]byte, []byte, error) {
|
||||
if this.errors != nil {
|
||||
this.Session.Close()
|
||||
return this.outbyte, this.errbyte, this.errors
|
||||
}
|
||||
if sleep > 0 {
|
||||
time.Sleep(time.Millisecond * time.Duration(sleep))
|
||||
}
|
||||
return this.outbyte, this.errbyte, nil
|
||||
}
|
||||
|
||||
func (this *StarShell) WriteCommand(cmd string) error {
|
||||
return this.Write([]byte(cmd + "\n"))
|
||||
}
|
||||
|
||||
func (this *StarShell) Write(bstr []byte) error {
|
||||
if this.errors != nil {
|
||||
this.Session.Close()
|
||||
return this.errors
|
||||
}
|
||||
_, err := this.in.Write(bstr)
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *StarShell) gohub() {
|
||||
go func() {
|
||||
var cache []byte
|
||||
for {
|
||||
read, err := this.er.ReadByte()
|
||||
if err != nil {
|
||||
this.errors = err
|
||||
return
|
||||
}
|
||||
this.errbyte = append(this.errbyte, read)
|
||||
if this.isprint {
|
||||
fmt.Print(string([]byte{read}))
|
||||
}
|
||||
cache = append(cache, read)
|
||||
if read == '\n' {
|
||||
if this.isfuncs {
|
||||
go this.funcs(this.TrimColor(strings.TrimSpace(string(cache))))
|
||||
cache = []byte{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
var cache []byte
|
||||
for {
|
||||
read, err := this.out.ReadByte()
|
||||
if err != nil {
|
||||
this.errors = err
|
||||
return
|
||||
}
|
||||
this.rw.Lock()
|
||||
this.outbyte = append(this.outbyte, read)
|
||||
cache = append(cache, read)
|
||||
this.rw.Unlock()
|
||||
if read == '\n' {
|
||||
if this.isfuncs {
|
||||
go this.funcs(strings.TrimSpace(string(cache)))
|
||||
cache = []byte{}
|
||||
}
|
||||
}
|
||||
if this.isprint {
|
||||
fmt.Print(string([]byte{read}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *StarShell) GetUid() string {
|
||||
res, _, _ := this.ShellWait(`id | grep -oP "(?<=uid\=)\d+"`)
|
||||
return strings.TrimSpace(res)
|
||||
}
|
||||
func (this *StarShell) GetGid() string {
|
||||
res, _, _ := this.ShellWait(`id | grep -oP "(?<=gid\=)\d+"`)
|
||||
return strings.TrimSpace(res)
|
||||
}
|
||||
func (this *StarShell) GetUser() string {
|
||||
res, _, _ := this.ShellWait(`id | grep -oP "(?<=\().*?(?=\))" | head -n 1`)
|
||||
return strings.TrimSpace(res)
|
||||
}
|
||||
func (this *StarShell) GetGroup() string {
|
||||
res, _, _ := this.ShellWait(`id | grep -oP "(?<=\().*?(?=\))" | head -n 2 | tail -n 1`)
|
||||
return strings.TrimSpace(res)
|
||||
}
|
||||
|
||||
func (this *StarSSH) NewShell() (shell *StarShell, err error) {
|
||||
shell = new(StarShell)
|
||||
shell.Session, err = this.NewSession()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
shell.in, _ = shell.Session.StdinPipe()
|
||||
tmp, _ := shell.Session.StdoutPipe()
|
||||
shell.out = bufio.NewReader(tmp)
|
||||
tmp, _ = shell.Session.StderrPipe()
|
||||
shell.er = bufio.NewReader(tmp)
|
||||
err = shell.Session.Shell()
|
||||
shell.isecho = true
|
||||
go shell.Session.Wait()
|
||||
shell.UseWaitDefault = true
|
||||
shell.WriteCommand("bash")
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
shell.WriteCommand("export PS1= ")
|
||||
shell.WriteCommand("export PS2= ")
|
||||
go shell.gohub()
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
shell.Clear()
|
||||
shell.Clear()
|
||||
return
|
||||
}
|
||||
|
||||
func (this *StarSSH) Close() error {
|
||||
if this.online {
|
||||
return this.Client.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *StarSSH) NewSession() (*ssh.Session, error) {
|
||||
return NewSession(this.Client)
|
||||
}
|
||||
|
||||
func (this *StarSSH) ShellOne(cmd string) (string, error) {
|
||||
newsess, err := this.NewSession()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
data, err := newsess.CombinedOutput(cmd)
|
||||
newsess.Close()
|
||||
return strings.TrimSpace(string(data)), err
|
||||
}
|
||||
|
||||
func (this *StarSSH) Exists(filepath string) bool {
|
||||
res, _ := this.ShellOne(`echo 1 && [ ! -e "` + filepath + `" ] && echo 2`)
|
||||
if res == "1" {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this *StarSSH) GetUid() string {
|
||||
res, _ := this.ShellOne(`id | grep -oP "(?<=uid\=)\d+"`)
|
||||
return strings.TrimSpace(res)
|
||||
}
|
||||
func (this *StarSSH) GetGid() string {
|
||||
res, _ := this.ShellOne(`id | grep -oP "(?<=gid\=)\d+"`)
|
||||
return strings.TrimSpace(res)
|
||||
}
|
||||
func (this *StarSSH) GetUser() string {
|
||||
res, _ := this.ShellOne(`id | grep -oP "(?<=\().*?(?=\))" | head -n 1`)
|
||||
return strings.TrimSpace(res)
|
||||
}
|
||||
func (this *StarSSH) GetGroup() string {
|
||||
res, _ := this.ShellOne(`id | grep -oP "(?<=\().*?(?=\))" | head -n 2 | tail -n 1`)
|
||||
return strings.TrimSpace(res)
|
||||
}
|
||||
|
||||
func (this *StarSSH) IsFile(filepath string) bool {
|
||||
res, _ := this.ShellOne(`echo 1 && [ ! -f "` + filepath + `" ] && echo 2`)
|
||||
if res == "1" {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this *StarSSH) IsFolder(filepath string) bool {
|
||||
res, _ := this.ShellOne(`echo 1 && [ ! -d "` + filepath + `" ] && echo 2`)
|
||||
if res == "1" {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this *StarSSH) ShellOneShowScreen(cmd string) (string, error) {
|
||||
newsess, err := this.NewSession()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var bytes, errbytes []byte
|
||||
tmp, _ := newsess.StdoutPipe()
|
||||
reader := bufio.NewReader(tmp)
|
||||
tmp, _ = newsess.StderrPipe()
|
||||
errder := bufio.NewReader(tmp)
|
||||
err = newsess.Start(cmd)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
c := make(chan int, 1)
|
||||
go newsess.Wait()
|
||||
go func() {
|
||||
for {
|
||||
byt, err := reader.ReadByte()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
fmt.Print(string([]byte{byt}))
|
||||
bytes = append(bytes, byt)
|
||||
}
|
||||
c <- 1
|
||||
}()
|
||||
for {
|
||||
byt, err := errder.ReadByte()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
fmt.Print(string([]byte{byt}))
|
||||
errbytes = append(errbytes, byt)
|
||||
}
|
||||
_ = <-c
|
||||
newsess.Close()
|
||||
if len(errbytes) != 0 {
|
||||
err = errors.New(strings.TrimSpace(string(errbytes)))
|
||||
} else {
|
||||
err = nil
|
||||
}
|
||||
return strings.TrimSpace(string(bytes)), err
|
||||
}
|
||||
|
||||
func (this *StarSSH) ShellOneToFunc(cmd string, callback func(string)) (string, error) {
|
||||
newsess, err := this.NewSession()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var bytes, errbytes []byte
|
||||
tmp, _ := newsess.StdoutPipe()
|
||||
reader := bufio.NewReader(tmp)
|
||||
tmp, _ = newsess.StderrPipe()
|
||||
errder := bufio.NewReader(tmp)
|
||||
err = newsess.Start(cmd)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
c := make(chan int, 1)
|
||||
go newsess.Wait()
|
||||
go func() {
|
||||
for {
|
||||
byt, err := reader.ReadByte()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
callback(string([]byte{byt}))
|
||||
bytes = append(bytes, byt)
|
||||
}
|
||||
c <- 1
|
||||
}()
|
||||
for {
|
||||
byt, err := errder.ReadByte()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
callback(string([]byte{byt}))
|
||||
errbytes = append(errbytes, byt)
|
||||
}
|
||||
_ = <-c
|
||||
newsess.Close()
|
||||
if len(errbytes) != 0 {
|
||||
err = errors.New(strings.TrimSpace(string(errbytes)))
|
||||
} else {
|
||||
err = nil
|
||||
}
|
||||
return strings.TrimSpace(string(bytes)), err
|
||||
}
|
||||
|
||||
func NewTransferSession(client *ssh.Client) (*ssh.Session, error) {
|
||||
session, err := client.NewSession()
|
||||
return session, err
|
||||
}
|
||||
|
||||
func NewSession(client *ssh.Client) (*ssh.Session, error) {
|
||||
var session *ssh.Session
|
||||
var err error
|
||||
// create session
|
||||
if session, err = client.NewSession(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
modes := ssh.TerminalModes{
|
||||
ssh.ECHO: 1, // 还是要强制开启
|
||||
//ssh.IGNCR: 0,
|
||||
ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
|
||||
ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
|
||||
}
|
||||
|
||||
if err := session.RequestPty("xterm", 500, 250, modes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func SedColor(str string) string {
|
||||
reg := regexp.MustCompile(`\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]`)
|
||||
//fmt.Println("regexp:", reg.Match([]byte(str)))
|
||||
return string(reg.ReplaceAll([]byte(str), []byte("")))
|
||||
}
|
Loading…
Reference in New Issue