<p>I want a way to replicate this command using ssh/crypto:</p>
<blockquote>
<p>ssh user@host /bin/bash < dummy.sh</p>
</blockquote>
<p>I can easily run binaries that's already in the host with simple</p>
<blockquote>
<p>session.Run(cmd)</p>
</blockquote>
<p>But I am having issues running complex command like this.</p>
<hr/>**评论:**<br/><br/>Perhyte: <pre><p>As <a href="/u/JHunz" rel="nofollow">/u/JHunz</a> said, the <code><</code> is not really part of the command line sent to the other machine. It just tells the <em>local</em> shell to connect <code>dummy.sh</code> to the stdin of the <code>ssh</code> command (which is why it only works if the file is locally available). It's pretty much exactly as if you typed the contents of that file into ssh, then pressed Ctrl+D to simulate EOF and close the command.</p>
<p>Now, as for how to replicate this in Go: the interface for <code>crypto/ssh.Session</code> seems to be similar to that of <code>os/Exec.Cmd</code>, so my guess would be something like:</p>
<pre><code>file, err := os.Open("dummy.sh")
if err != null { return err; }
defer file.Close()
session.Stdin = file
session.Run(cmd)
</code></pre>
<p>Disclaimer: I've never had occasion to use the <code>crypto/ssh</code> package.</p></pre>titpetric: <pre><p>The cmd here should be something like "bash -c" for crypto/ssh, or "ssh user@host bash -c" for using os/exec, as a slice ofc. +1 on the explanation.</p>
<p>It's also possible to copy the originating script to the remote machine by running <code>cat > /tmp/outfile.sh</code> as the cmd. The file will be sent to Stdin, cat which executes on the remote host will read from it, and then write the contents into a file on the system. It might be better do so it like this, just so there's no weird tty issues or whatever (I haven't hit them myself, but some things require a tty and break if you don't have one).</p></pre>JHunz: <pre><p>The reading of the file and passing it in via the < is part of the shell, not SSH, so it's no wonder you're having trouble replicating it using just the SSH package. I'm guessing the best approach is to read the whole script in, then pass it all as the cmd to Session.Run</p></pre>pzduniak: <pre><p>You should execute it in sh -c - otherwise you'd pollute the system with temporary scripts.</p></pre>janderssen: <pre><p>Ignoring best practises (ie error handling), the basic way I do this in our server is as follows :</p>
<pre><code>signer, err := ssh.ParsePrivateKey([]byte(connectionInfo.PrivateKey))
sshConfig := &ssh.ClientConfig{
User: connectionInfo.UserID,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
Timeout: time.Second * 5,
}
conn, err := net.DialTimeout("tcp", connectionInfo.AddressString(), sshConfig.Timeout)
..
c, chans, reqs, err := ssh.NewClientConn(conn, connectionInfo.AddressString(), sshConfig)
..
client = ssh.NewClient(c, chans, reqs)
</code></pre>
<p>So to run a command </p>
<pre><code>session, err := client.NewSession()
var b bytes.Buffer
session.Stdout = &b
session.Run("ls -l") // or what ever you want to execute
</code></pre>
<p>b contains output</p>
<p>Copy a script to the server for execution:</p>
<pre><code>session, err := client.NewSession()
bytesReader := bytes.NewReader(bytesToWrite)
scp.Copy(int64(len(bytesToWrite)), 0644, filename, bytesReader, path, session)
</code></pre>
<p>I hope this helps.</p></pre>notacyborg-v0: <pre><p>Thanks, I have been trying to avoid doing that but looks like this is the only way out. Let me try it.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传