第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

在使用管道執(zhí)行 go binary 時(shí)使用 scanln

在使用管道執(zhí)行 go binary 時(shí)使用 scanln

Go
慕工程0101907 2022-01-17 10:11:50
我有以下代碼:package mainimport "fmt"func main() {    if scanln_test() {        fmt.Println("Success!")    }}func scanln_test() bool {    fmt.Print("Please type yes or no and then press enter [y/n]: ")    var response string    fmt.Scanln(&response)    if response == "y" {        return true    } else if response == "n" {        return false    } else {        return scanln_test()    }}通過管道執(zhí)行編譯后的二進(jìn)制文件時(shí),例如:$ echo "just-showing-how-pipe-affects-the-behavior" | ./scanln我得到函數(shù)fmt.Print內(nèi)部的無限輸出。scanln_test但是,當(dāng)我不通過管道執(zhí)行它時(shí),一切正常。有沒有辦法解決這個(gè)問題?UPD。當(dāng)使用管道執(zhí)行二進(jìn)制文件時(shí),fmt.Scanln 返回“EOF”作為錯(cuò)誤UPD2。上面帶有 echo 的示例只是為了說明管道,但我不想在我的 go 程序中閱讀此 echo 的內(nèi)容。真實(shí)案例如下所示:wget -qO- http://example.com/get | sh -s "param". 我在這個(gè)下載的 shell 腳本中有執(zhí)行 go 程序,我希望我的程序用 Y/N 向用戶顯示對話。我不確定這是否可能,所以現(xiàn)在我決定擺脫管道并像wget -qO- http://example.com/get | sh && go-program "param".
查看完整描述

2 回答

?
呼啦一陣風(fēng)

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超6個(gè)贊

因此,您需要來自 Stdin(管道)和用戶 Stdin(鍵盤)的并發(fā)輸入:

我認(rèn)為您的答案是 cat 命令,請參閱:如何將初始輸入通過管道傳輸?shù)竭M(jìn)程中,然后該進(jìn)程將是交互式的?

和:https://en.wikipedia.org/wiki/Cat_(Unix)


請參閱:如何在 Go 中通過管道傳輸多個(gè)命令?

并進(jìn)行進(jìn)程間通信


有 3 件事需要注意:

首先:檢查所有錯(cuò)誤是一個(gè)好習(xí)慣:

在您的情況下:


n, err := fmt.Scanln(&response)  

第二:

您正在使用遞歸調(diào)用(Tail Call),這里沒有必要。

用簡單的 for 循環(huán)替換它并查看: Go

3 中的尾調(diào)用優(yōu)化:

最后但并非最不重要的一點(diǎn):如果輸入錯(cuò)誤,您的代碼將永遠(yuǎn)循環(huán)(如果編譯器無法優(yōu)化尾調(diào)用,則消耗堆棧)!

最好限制在 3 個(gè)。

例如:


package main


import "fmt"

import "strings"


type Input int


const (

    Timeout Input = iota

    Yes

    No

    Abort

    BadInput

)


func userInput(msg string) Input {

    var input string

    for i := 0; i < 3; i++ {

        fmt.Println(msg)

        n, err := fmt.Scanln(&input)

        if n > 0 {

            switch strings.ToLower(input) {

            case "y":

                return Yes

            case "n":

                return No

            case "a":

                return Abort

            }

        }

        if err != nil {

            return BadInput // or panic(err)

        }

    }

    return Timeout

}

func main() {

    ans := userInput("Please type Yes,No or Abort and then press enter [y/n/a]: ")

    fmt.Println(ans)

    switch ans {

    case Yes:

        fmt.Println("Yes") // do some job

        //...

    }

}

編輯:使用這個(gè)簡單的“y/n”,您無需檢查它是否是管道。

即使是帶有一個(gè)字節(jié)切片的簡單 std Read 也很好:


os.Stdin.Read(b1)

查看我的管道示例:https ://stackoverflow.com/a/37334984/6169399


但如果您的標(biāo)準(zhǔn)輸入是管道,您可以使用:


bytes, err := ioutil.ReadAll(os.Stdin) 

一次讀取所有管道數(shù)據(jù)。但要小心處理錯(cuò)誤。您可以檢查標(biāo)準(zhǔn)輸入是否與終端或管道相關(guān)聯(lián),然后使用適當(dāng)?shù)拇a。

檢測它的簡單方法是否是管道:


package main


import (

    "fmt"

    "os"

)


func main() {

    info, err := os.Stdin.Stat()

    if err != nil {

        fmt.Println("not a pipe")

    } else {

        fmt.Println("pipe name=", info.Name(), "pipe size=", info.Size())

    }

}

全部在一個(gè)示例代碼中:


package main


import (

    "fmt"

    "io/ioutil"

    "os"

    "strings"

)


type Input int


const (

    Timeout Input = iota

    Yes

    No

    Abort

    BadInput

)


func userInput(msg string) Input {

    var input string

    for i := 0; i < 3; i++ {

        fmt.Println(msg)

        n, err := fmt.Scanln(&input)

        if n > 0 {

            switch strings.ToLower(input) {

            case "y":

                return Yes

            case "n":

                return No

            case "a":

                return Abort

            }

        }

        if err != nil {

            return BadInput // or panic(err)

        }

    }

    return Timeout

}

func main() {

    info, err := os.Stdin.Stat()

    if err != nil {

        //fmt.Println("not a pipe")

        ans := userInput("Please type Yes,No or Abort and then press enter [y/n/a]: ")

        fmt.Println(ans)

        switch ans {

        case Yes:

            fmt.Println("Yes") // do some job

            //...

        }


    } else {

        fmt.Println("pipe name=", info.Name(), "pipe size=", info.Size())

        bytes, err := ioutil.ReadAll(os.Stdin)

        fmt.Println(string(bytes), err) //do some jobe with bytes

    }


}



查看完整回答
反對 回復(fù) 2022-01-17
?
明月笑刀無情

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超4個(gè)贊

您可以使用os.ModeCharDevice:


stat, _ := os.Stdin.Stat()


if (stat.Mode() & os.ModeCharDevice) == 0 {

    // piped

    input, _ := ioutil.ReadAll(os.Stdin)

} else {

    // not piped, do whatever, like fmt.Scanln()

}


查看完整回答
反對 回復(fù) 2022-01-17
  • 2 回答
  • 0 關(guān)注
  • 174 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號