簡體   English   中英

從* os.file復制Golang而無需等待EOF

[英]Golang copy from *os.file without hanging on waiting for EOF

我正在嘗試使用io.Copy從文件復制,它在實際從其內部緩沖區復制字節之前等待EOF,對嗎? 在我的用例(PTY / SSH會話)中,EOF僅在會話完成時才出現,這意味着我一直在瞎瞎,直到會話確定會話結束為止。

我嘗試一次使用1個字節的CopyN可以正常工作,但是如果我嘗試等待出現一些特定的文本,然后復制過去推送到文件中的內容,則代碼將掛起,我失去會議。 是否有一個功能可以“讀取那里的內容”然后停止,或者有其他標記(例如EOF)可以告訴復制現在停止?

我也嘗試讀取ptyI.pty指向的文件的內容,但它始終返回0字節,因此我無法在那里檢查更新

這是目前處理它的代碼:

type PtyInterface struct {
    pty          *os.File
    buf          *bytes.Buffer
}

func (ptyI *PtyInterface) PrivCmd(cmdStr string) (string, error) {

    // Copy the command provided into the STDIN of the bash shell we opened with
    // the earlier PtyInterface
    _, _ = io.Copy(ptyI.pty, strings.NewReader(string("somecommand")))

    // Assuming everything has gone well, we wait for the prompt to appear

    // We do this by running through individual bytes until the prompt is
    // fully printed (otherwise we might try to send in the answer at the wrong time)
    for !strings.HasSuffix(ptyI.buf.String(), "Prompt question? ") {
        _, _ = io.CopyN(ptyI.buf, ptyI.pty, 1)
    }

    // Once we hit the prompt we throw the answer into STDIN along with a newline
    // and the bash shell should accept this and begin executing the command.
    _, _ = io.Copy(ptyI.pty, strings.NewReader(string("answer\n")))

    // If we dont throw an exit in there then the PTY will never receive an EOF marker and we'll
    // hang on the next copy
    _, _ = io.Copy(ptyI.pty, strings.NewReader(string("exit\n")))

    // Now this copy will wait for an EOF
    _, _ = io.Copy(ptyI.buf, ptyI.pty)

    //Debug info to be printed after
    fmt.Println("\nBytes written to buffer (newone): \n" + ptyI.buf.String())

    return ptyI.buf.String(), nil
}

可以將io.Copy視為用於批量復制或流的io.Copy功能,而不是用於請求/響應模式的正確工具。

只需通過檢查字節是否與每個字節上的消息匹配來將字節累積到消息中即可。 直接使用Read方法。

func Expect(message string, r io.Reader) (resp string, err error) {
    b := []byte{0} // 1 byte buffer
    var n int

    for err == nil {
        n, err = r.Read(b)
        if n == 0 {
            continue
        }
        resp += string(b[0])
        if strings.HasSuffix(resp, message) {
            return resp, err
        }
    }

    return resp, err
}

在您的示例中,您可以這樣使用:

resp, err := Expect("Prompt question? ", ptyI.pty)

下面是它在行動示范與模擬連接io.Reader: 操場

相當於貓&lt; <eof in golang< div><div id="text_translate"><p> 我正在嘗試執行等效的操作:</p><pre> cat &lt;&lt;EOF | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: name: testMap namespace: default data: details: host: "localhost:${reg_port}" EOF</pre><p> 在戈朗。</p><p> 我目前的嘗試歸結為:</p><pre> func generateConfig(port string) string { return ` apiVersion: v1 kind: ConfigMap metadata: name: testMap namespace: default data: details: host: "localhost:" + port` } func main() { exec.Command("kubectl", "apply", "-f", "-", generateConfig(5000)) }</pre><p> 發現它不起作用並出現錯誤,我並不感到特別驚訝:</p><pre> error: Unexpected args: [ apiVersion: v1 kind: ConfigMap metadata: name: testMap namespace: default data: details: host: "localhost:5000"]</pre><p> 我認識到我將這些作為 args 傳遞並且 kubectl 需要一個文件,但是我發現自己完全不知道如何繼續。</p><p> 我寧願不制作臨時文件或調用單獨的 bash 腳本,因為這看起來比我希望的必要要復雜。</p></div></eof>

[英]Equivalent to cat <<EOF in golang

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

相關問題 相當於貓&lt; <eof in golang< div><div id="text_translate"><p> 我正在嘗試執行等效的操作:</p><pre> cat &lt;&lt;EOF | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: name: testMap namespace: default data: details: host: "localhost:${reg_port}" EOF</pre><p> 在戈朗。</p><p> 我目前的嘗試歸結為:</p><pre> func generateConfig(port string) string { return ` apiVersion: v1 kind: ConfigMap metadata: name: testMap namespace: default data: details: host: "localhost:" + port` } func main() { exec.Command("kubectl", "apply", "-f", "-", generateConfig(5000)) }</pre><p> 發現它不起作用並出現錯誤,我並不感到特別驚訝:</p><pre> error: Unexpected args: [ apiVersion: v1 kind: ConfigMap metadata: name: testMap namespace: default data: details: host: "localhost:5000"]</pre><p> 我認識到我將這些作為 args 傳遞並且 kubectl 需要一個文件,但是我發現自己完全不知道如何繼續。</p><p> 我寧願不制作臨時文件或調用單獨的 bash 腳本,因為這看起來比我希望的必要要復雜。</p></div></eof> Docker:不掛尾日志文件 如何將所有行從文件傳送到EOF? 將文件從存儲桶拆分並復制到另一個存儲桶,而無需在本地下載 使用packer將文件從主機復制到生成的映像,無需密碼 從OS / X終端將文本復制到剪貼板 EOF到遠程主機上的文件 從python運行外部程序:無需等待所有輸出的管道 復制系統文件沒有shell cp命令 從文件中復制文件列表
 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM