Go言語呼び出しShellと実行可能ファイル

4194 ワード

os/execパッケージは、外部コマンドを呼び出すために使用できます.パイプを使用して入出力を接続し、ブロックと非ブロックでコマンドを実行することをサポートします.os/execパッケージの重要なタイプはCmdです.以下に説明するすべての方法はこのタイプにサービスします.
  • func Command(name string, arg ...string) *Cmd *Cmd, name ( arg )
  • func (c *Cmd) Run() error Cmd ,
  • func (c *Cmd) Start() error Cmd , ,
  • func (c *Cmd) Wait() error Cmd , Start
  • func (c *Cmd) Output() ([]byte, error) Cmd ,
  • func (c *Cmd) CombinedOutput() ([]byte, error) Cmd ,
  • func (c *Cmd) StdinPipe() (io.WriteCloser, error) , Cmd
  • func (c *Cmd) StdoutPipe() (io.ReadCloser, error) , Cmd
  • func (c *Cmd) StderrPipe() (io.ReadCloser, error) , Cmd

  • 一般的な呼び出しの例:
    Shellコマンドまたは実行可能ファイルの呼び出し
    プレゼンテーション現在のディレクトリに空のファイルを作成する
    package main
    
    import (
        "fmt"
        "os/exec"
    )
    
    func main(){
        cmd := exec.Command("touch", "test_file")
    
        err := cmd.Run()
        if err != nil {
            fmt.Println("Execute Command failed:" + err.Error())
            return
        }
    
        fmt.Println("Execute Command finished.")
    }
    

    一般的に、このデフォルト方式でShellスクリプトを呼び出すことは推奨されません.cmd := exec.Command("my_shell.sh")は、この方式の実際の実行結果がコマンドライン実行#sh my_shell.shと同じであるため、Shellスクリプトがshの仕様を満たさない場合、呼び出すことに失敗します.
    シェルスクリプトの呼び出し
    指定したShellスクリプトを呼び出すにはbashを設定し、dir_size.shはテスト用のShellスクリプトです.呼び出し完了後にShellスクリプトを印刷する標準はコンソールに出力されます.
    package main
    
    import (
        "fmt"
        "os/exec"
    )
    
    func main(){
        command := `./dir_size.sh .`
        cmd := exec.Command("/bin/bash", "-c", command)
    
        output, err := cmd.Output()
        if err != nil {
            fmt.Printf("Execute Shell:%s failed with error:%s", command, err.Error())
            return
        }
        fmt.Printf("Execute Shell:%s finished with output:
    %s", command, string(output)) }
    dir_size.shのファイルの例は、現在のディレクトリのサイズを出力するために以下のとおりです.
    #!/bin/bash
    du -h --max-depth=1 $1
    

    Goプログラムの実行結果:
    [root@localhost opt]# ll
    total 2120
    -rwx------.  1 root root      36 Jan 22 16:37 dir_size.sh
    -rwx------.  1 root root 2152467 Jan 22 16:39 execCommand
    drwxrwxr-x. 11 1000 1000    4096 Jul 12  2017 kibana
    drwx------.  2 root root    4096 Jan 16 10:45 sftpuser
    drwx------.  3 root root    4096 Jan 22 16:41 upload
    [root@localhost opt]# ./execCommand 
    Execute Shell:./dir_size.sh . finished with output:
    4.0K    ./sftpuser
    181M    ./kibana
    1.1G    ./upload
    1.2G    .
    

    入出力Pipeの使用
    デモでは、grepコマンドに接続するパイプを使用する標準入力を示し、testを含む文字列をフィルタし、パイプ接続標準出力を使用して、実行結果を印刷します.
    package main
    
    import (
        "fmt"
        "io/ioutil"
        "os/exec"
    )
    
    func main(){
        cmd := exec.Command("/bin/bash", "-c", "grep test")
    
        stdin, _ := cmd.StdinPipe()
        stdout, _ := cmd.StdoutPipe()
    
        if err := cmd.Start(); err != nil{
            fmt.Println("Execute failed when Start:" + err.Error())
            return
        }
    
        stdin.Write([]byte("go text for grep
    ")) stdin.Write([]byte("go test text for grep
    ")) stdin.Close() out_bytes, _ := ioutil.ReadAll(stdout) stdout.Close() if err := cmd.Wait(); err != nil { fmt.Println("Execute failed when Wait:" + err.Error()) return } fmt.Println("Execute finished:" + string(out_bytes)) }

    Goプログラムの実行結果:
    [root@localhost ~]# ./execCommand 
    Execute finished:go test text for grep
    
    

    ブロック/非ブロック方式呼び出し
    文章の冒頭の方法の紹介所はすでにはっきりしていて、前の例はすべて関連していて、別に説明しません.
    参考ドキュメント:GoLang標準ライブラリドキュメント