Last active
          September 10, 2025 02:55 
        
      - 
      
- 
        Save iamralch/b7f56afc966a6b6ac2fc to your computer and use it in GitHub Desktop. 
Revisions
- 
        iamralch revised this gist Jul 20, 2015 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -35,9 +35,9 @@ func (client *SSHClient) RunCommand(cmd *SSHCommand) error { if session, err = client.newSession(); err != nil { return err } defer session.Close() if err = client.prepareCommand(session, cmd); err != nil { return err } 
- 
        iamralch created this gist Jul 18, 2015 .There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,160 @@ package main import ( "fmt" "io" "io/ioutil" "net" "os" "strings" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" ) type SSHCommand struct { Path string Env []string Stdin io.Reader Stdout io.Writer Stderr io.Writer } type SSHClient struct { Config *ssh.ClientConfig Host string Port int } func (client *SSHClient) RunCommand(cmd *SSHCommand) error { var ( session *ssh.Session err error ) if session, err = client.newSession(); err != nil { return err } if err = client.prepareCommand(session, cmd); err != nil { session.Close() return err } err = session.Run(cmd.Path) return err } func (client *SSHClient) prepareCommand(session *ssh.Session, cmd *SSHCommand) error { for _, env := range cmd.Env { variable := strings.Split(env, "=") if len(variable) != 2 { continue } if err := session.Setenv(variable[0], variable[1]); err != nil { return err } } if cmd.Stdin != nil { stdin, err := session.StdinPipe() if err != nil { return fmt.Errorf("Unable to setup stdin for session: %v", err) } go io.Copy(stdin, cmd.Stdin) } if cmd.Stdout != nil { stdout, err := session.StdoutPipe() if err != nil { return fmt.Errorf("Unable to setup stdout for session: %v", err) } go io.Copy(cmd.Stdout, stdout) } if cmd.Stderr != nil { stderr, err := session.StderrPipe() if err != nil { return fmt.Errorf("Unable to setup stderr for session: %v", err) } go io.Copy(cmd.Stderr, stderr) } return nil } func (client *SSHClient) newSession() (*ssh.Session, error) { connection, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", client.Host, client.Port), client.Config) if err != nil { return nil, fmt.Errorf("Failed to dial: %s", err) } session, err := connection.NewSession() if err != nil { return nil, fmt.Errorf("Failed to create session: %s", err) } modes := ssh.TerminalModes{ // ssh.ECHO: 0, // disable echoing ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } if err := session.RequestPty("xterm", 80, 40, modes); err != nil { session.Close() return nil, fmt.Errorf("request for pseudo terminal failed: %s", err) } return session, nil } func PublicKeyFile(file string) ssh.AuthMethod { buffer, err := ioutil.ReadFile(file) if err != nil { return nil } key, err := ssh.ParsePrivateKey(buffer) if err != nil { return nil } return ssh.PublicKeys(key) } func SSHAgent() ssh.AuthMethod { if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil { return ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers) } return nil } func main() { // ssh.Password("your_password") sshConfig := &ssh.ClientConfig{ User: "jsmith", Auth: []ssh.AuthMethod{ SSHAgent(), }, } client := &SSHClient{ Config: sshConfig, Host: "example.com", Port: 22, } cmd := &SSHCommand{ Path: "ls -l $LC_DIR", Env: []string{"LC_DIR=/"}, Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, } fmt.Printf("Running command: %s\n", cmd.Path) if err := client.RunCommand(cmd); err != nil { fmt.Fprintf(os.Stderr, "command run error: %s\n", err) os.Exit(1) } }