Need help displaying the execution output of a shell command, e.g. rsync. that takes a while to run

agolangf · · 483 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Basically, user provides a list of files to copy from dest1 to dest2. rsync is fired off by pressing the submitting the button, and I want the realtime output of STDOUT/STDERR display in the same page. I would also be saving this execution as a blob in a MySQL DB. WebSockets?</p> <hr/>**评论:**<br/><br/>AG_Clinton: <pre><p>I did almost exactly that with a python script that ran rsync. I&#39;ll show you a very stripped down version of what I have. This is my first time doing something like this and I&#39;m still a beginner, but figured I&#39;d share what worked for me. I used gorilla websockets. I&#39;m sure it could be simplified quite a bit as well.</p> <pre><code>var ( SyncOutput = make(chan string) SyncClients = make(map[*websocket.Conn]bool) SyncClientsLock = sync.RWMutex{} FileSyncing = false FileSyncLock = sync.RWMutex{} ) var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, } go WatchOutPutChannel() func runSync() { cmd := exec.Command(&#34;python&#34;, &#34;-u&#34;, config.SyncFilesScript) stdout, err := cmd.StdoutPipe() if err != nil { fmt.Println(fmt.Sprintf(&#34;Error: %s&#34;, err)) } FileSyncLock.Lock() FileSyncing = true FileSyncLock.Unlock() err = cmd.Start() go WatchOutPut(stdout) } func WatchOutPut(out io.Reader) { scanner := bufio.NewScanner(out) for scanner.Scan() { SyncOutput &lt;- scanner.Text() } FileSyncLock.Lock() FileSyncing = false FileSyncLock.Unlock() SyncOutput &lt;- &#34;Sync Finished&#34; } func WatchOutPutChannel() { for { output := &lt;-SyncOutput SyncClientsLock.RLock() for client := range SyncClients { client.WriteMessage(1, []byte(output)) } SyncClientsLock.RUnlock() } } func wsHandlerSync(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println(&#34;Failed to set websocket upgrade: %+v&#34;, err) return } SyncClientsLock.Lock() SyncClients[conn] = true SyncClientsLock.Unlock() for { _, _, err := conn.ReadMessage() if err != nil { break } } SyncClientsLock.Lock() delete(SyncClients, conn) SyncClientsLock.Unlock() conn.Close() } </code></pre></pre>dazealex: <pre><p>Thank you kind sir! Much appreciated. </p></pre>toolateforTeddy: <pre><p>Websockets seems like a good plan.</p> <p>I like gorilla websockets.</p></pre>dazealex: <pre><p>Any examples?</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

483 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传