<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] # api ~~~ func (*Cmd) Run func (c *Cmd) Run() error Run執行c包含的命令,并阻塞直到完成。 如果命令成功執行,stdin、stdout、stderr的轉交沒有問題,并且返回狀態碼為0,方法的返回值為nil;如果命令沒有執行或者執行失敗,會返回*ExitError類型的錯誤;否則返回的error可能是表示I/O問題。 ~~~ ~~~ func (*Cmd) Start func (c *Cmd) Start() error Start開始執行c包含的命令,但并不會等待該命令完成即返回。Wait方法會返回命令的返回狀態碼并在命令返回后釋放相關的資源。 ~~~ ~~~ func (*Cmd) Wait func (c *Cmd) Wait() error Wait會阻塞直到該命令執行完成,該命令必須是被Start方法開始執行的。 如果命令成功執行,stdin、stdout、stderr的轉交沒有問題,并且返回狀態碼為0,方法的返回值為nil;如果命令沒有執行或者執行失敗,會返回*ExitError類型的錯誤;否則返回的error可能是表示I/O問題。Wait方法會在命令返回后釋放相關的資源。 ~~~ ~~~ func (*Cmd) Output func (c *Cmd) Output() ([]byte, error) 執行命令并返回標準輸出的切片。 ~~~ ~~~ func (*Cmd) StderrPipe func (c *Cmd) StderrPipe() (io.ReadCloser, error) StderrPipe方法返回一個在命令Start后與命令標準錯誤輸出關聯的管道。Wait方法獲知命令結束后會關閉這個管道,一般不需要顯式的關閉該管道。但是在從管道讀取完全部數據之前調用Wait是錯誤的;同樣使用StderrPipe方法時調用Run函數也是錯誤的。 ~~~ # 阻塞方式(需要執行結果) 主要用于執行shell命令,并且返回shell的標準輸出 ## 適用于執行普通非阻塞shell命令,且需要shell標準輸出的 ~~~ //阻塞式的執行外部shell命令的函數,等待執行完畢并返回標準輸出 func exec_shell(s string) (string, error){ //函數返回一個*Cmd,用于使用給出的參數執行name指定的程序 cmd := exec.Command("/bin/bash", "-c", s) //讀取io.Writer類型的cmd.Stdout,再通過bytes.Buffer(緩沖byte類型的緩沖器)將byte類型轉化為string類型(out.String():這是bytes類型提供的接口) var out bytes.Buffer cmd.Stdout = &out //Run執行c包含的命令,并阻塞直到完成。 這里stdout被取出,cmd.Wait()無法正確獲取stdin,stdout,stderr,則阻塞在那了 err := cmd.Run() checkErr(err) return out.String(), err } ~~~ ## 需要對shell標準輸出的**逐行實時**進行處理的 ~~~ func execCommand(commandName string, params []string) bool { //函數返回一個*Cmd,用于使用給出的參數執行name指定的程序 cmd := exec.Command(commandName, params...) //顯示運行的命令 fmt.Println(cmd.Args) //StdoutPipe方法返回一個在命令Start后與命令標準輸出關聯的管道。Wait方法獲知命令結束后會關閉這個管道,一般不需要顯式的關閉該管道。 stdout, err := cmd.StdoutPipe() if err != nil { fmt.Println(err) return false } cmd.Start() //創建一個流來讀取管道內內容,這里邏輯是通過一行一行的讀取的 reader := bufio.NewReader(stdout) //實時循環讀取輸出流中的一行內容 for { line, err2 := reader.ReadString('\n') if err2 != nil || io.EOF == err2 { break } fmt.Println(line) } //阻塞直到該命令執行完成,該命令必須是被Start方法開始執行的 cmd.Wait() return true } ~~~ # 非阻塞方式(不需要執行結果) 通過shell調用自己的程序,并且程序是死循環,此時無法獲取返回結果(否則程序會一直阻塞直至調用的 程序結束) **適用于調用自己寫的程序(服務器死循環,且不需要返回結果的)** ~~~ //不需要執行命令的結果與成功與否,執行命令馬上就返回 func exec_shell_no_result(command string) { //處理啟動參數,通過空格分離 如:setsid /home/luojing/gotest/src/test_main/iwatch/test/while_little & command_name_and_args := strings.FieldsFunc(command, splite_command) //開始執行c包含的命令,但并不會等待該命令完成即返回 cmd.Start() if err != nil { fmt.Printf("%v: exec command:%v error:%v\n", get_time(), command, err) } fmt.Printf("Waiting for command:%v to finish...\n", command) //阻塞等待fork出的子進程執行的結果,和cmd.Start()配合使用[不等待回收資源,會導致fork出執行shell命令的子進程變為僵尸進程] err = cmd.Wait() if err != nil { fmt.Printf("%v: Command finished with error: %v\n", get_time(), err) } return } ~~~ ~~~ /錯誤處理函數 func checkErr(err error) { if err != nil { fmt.Println(err) panic(err) } } ~~~ # ssh ~~~ go get golang.org/x/crypto/ssh ~~~ ## ssh執行命令 這個方法需要有一個環境的準備:與目標服務器建立免密碼登陸],并且執行程序的用戶與執行用戶一致 ~~~ import ( "net" "log" "fmt" "bytes" "os/exec" "strconv" str "strings" "golang.org/x/crypto/ssh" ) func runCmd(){ var stdOut, stdErr bytes.Buffer cmd := exec.Command( "ssh", "username@192.168.1.4", "if [ -d liujx/project ];then echo 0;else echo 1;fi" ) cmd.Stdout = &stdOut cmd.Stderr = &stdErr if err := cmd.Run(); err != nil { fmt.Printf( "cmd exec failed: %s : %s", fmt.Sprint( err ), stdErr.String() ) } fmt.Print( stdOut.String() ) ret, err := strconv.Atoi( str.Replace( stdOut.String(), "\n", "", -1 ) ) if err != nil { panic(err) } fmt.Printf("%d, %s\n", ret, stdErr.String() ) } ~~~ ## ssh客戶端連接 這種方法可以不用搭建免密碼登陸環境,連接時可指定用戶和密碼的 ~~~ func SSHConnect( user, password, host string, port int ) ( *ssh.Session, error ) { var ( auth []ssh.AuthMethod addr string clientConfig *ssh.ClientConfig client *ssh.Client session *ssh.Session err error ) // get auth method auth = make([]ssh.AuthMethod, 0) auth = append(auth, ssh.Password(password)) hostKeyCallbk := func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil } clientConfig = &ssh.ClientConfig{ User: user, Auth: auth, // Timeout: 30 * time.Second, HostKeyCallback: hostKeyCallbk, } // connet to ssh addr = fmt.Sprintf( "%s:%d", host, port ) if client, err = ssh.Dial( "tcp", addr, clientConfig ); err != nil { return nil, err } // create session if session, err = client.NewSession(); err != nil { return nil, err } return session, nil } func runSsh(){ var stdOut, stdErr bytes.Buffer session, err := SSHConnect( "username", "passworld", "192.168.1.4", 22 ) if err != nil { log.Fatal(err) } defer session.Close() session.Stdout = &stdOut session.Stderr = &stdErr session.Run("if [ -d liujx/project ]; then echo 0; else echo 1; fi") ret, err := strconv.Atoi( str.Replace( stdOut.String(), "\n", "", -1 ) ) if err != nil { panic(err) } fmt.Printf("%d, %s\n", ret, stdErr.String() ) } ~~~ # os.Args ~~~ func main() { osArg := os.Args //[]string /** o 開始,第一個是文件路徑 */ for i, data := range osArg { fmt.Println(i, data) } } ~~~ # flag命令行參數 每個處理一行 ~~~ func main() { var recusive bool var test string var level int flag.BoolVar(&recusive, "r", false, "recusive xxx") flag.StringVar(&test, "t","default string", "string option") flag.IntVar(&level, "l", 1, "level of xxx") flag.Parse() fmt.Println(recusive) fmt.Println(test) fmt.Println(level) } ~~~ 不傳就給默認值 ~~~ ? studygo ./studygo false default string 1 ~~~ 傳遞就按照傳遞的來 ~~~ ? studygo ./studygo -r -t hello -l 11 true hello 11 ~~~ # urfave/cli框架 可以通過-h查看幫助 ~~~ import ( "fmt" "github.com/urfave/cli" "os" ) func main() { var language string var recusive bool app := cli.NewApp() //指定名字 app.Name = "greet" app.Usage = "用法" app.Flags = []cli.Flag{ cli.StringFlag{ Name: "lang, l", Value: "english", Usage: "select language", Destination: &language, }, cli.BoolFlag{ Name: "recusive, r", Usage: "recusive for the greeting", Destination: &recusive, }, } app.Action = func(c *cli.Context) error { var cmd string //如果用戶傳過來 >0 if c.NArg() > 0 { cmd = c.Args()[0] fmt.Println("cmd is ", cmd) } fmt.Println("recusive is: ", recusive) fmt.Println("language is: ", language) return nil } app.Run(os.Args) } ~~~ # 啟動外部命令和程序 os 包有一個`StartProcess`函數可以調用或啟動外部系統命令和二進制可執行文件;它的第一個參數是要運行的進程,第二個參數用來傳遞選項或參數,第三個參數是含有系統環境基本信息的結構體。 這個函數返回被啟動進程的 id(pid),或者啟動失敗返回錯誤。 exec 包中也有同樣功能的更簡單的結構體和函數;主要是`exec.Command(name string, arg ...string)`和`Run()`。首先需要用系統命令或可執行文件的名字創建一個`Command`對象,然后用這個對象作為接收者調用`Run()`。下面的程序(因為是執行 Linux 命令,只能在 Linux 下面運行)演示了它們的使用: ~~~ // exec.go package main import ( "fmt" "os/exec" "os" ) func main() { // 1) os.StartProcess // /*********************/ /* Linux: */ env := os.Environ() procAttr := &os.ProcAttr{ Env: env, Files: []*os.File{ os.Stdin, os.Stdout, os.Stderr, }, } // 1st example: list files pid, err := os.StartProcess("/bin/ls", []string{"ls", "-l"}, procAttr) if err != nil { fmt.Printf("Error %v starting process!", err) // os.Exit(1) } fmt.Printf("The process id is %v", pid) ~~~ 輸出: ~~~ The process id is &{2054 0}total 2056 -rwxr-xr-x 1 ivo ivo 1157555 2011-07-04 16:48 Mieken_exec -rw-r--r-- 1 ivo ivo 2124 2011-07-04 16:48 Mieken_exec.go -rw-r--r-- 1 ivo ivo 18528 2011-07-04 16:48 Mieken_exec_go_.6 -rwxr-xr-x 1 ivo ivo 913920 2011-06-03 16:13 panic.exe -rw-r--r-- 1 ivo ivo 180 2011-04-11 20:39 panic.go ~~~ ~~~ // 2nd example: show all processes pid, err = os.StartProcess("/bin/ps", []string{"-e", "-opid,ppid,comm"}, procAttr) if err != nil { fmt.Printf("Error %v starting process!", err) // os.Exit(1) } fmt.Printf("The process id is %v", pid) ~~~ ~~~ // 2) exec.Run // /***************/ // Linux: OK, but not for ls ? // cmd := exec.Command("ls", "-l") // no error, but doesn't show anything ? // cmd := exec.Command("ls") // no error, but doesn't show anything ? cmd := exec.Command("gedit") // this opens a gedit-window err = cmd.Run() if err != nil { fmt.Printf("Error %v executing command!", err) os.Exit(1) } fmt.Printf("The command is %v", cmd) // The command is &{/bin/ls [ls -l] [] <nil> <nil> <nil> 0xf840000210 <nil> true [0xf84000ea50 0xf84000e9f0 0xf84000e9c0] [0xf84000ea50 0xf84000e9f0 0xf84000e9c0] [] [] 0xf8400128c0} } // in Windows: uitvoering: Error fork/exec /bin/ls: The system cannot find the path specified. starting process! ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看