how to pipe the output from exec.Command into another commands in Golang

huangapple go评论136阅读模式
英文:

how to pipe the output from exec.Command into another commands in Golang

问题

我有八个Microsoft Access数据库,每个数据库大约有215个表,我需要将这些数据库转移到PostgreSQL中,所以我使用了mdb-tools并导出了模式,这只是一个步骤;但是当涉及将表数据直接导出到PostgreSQL时,我必须为每个表编写以下命令:

mdb-export -I postgres -q ' myaccessdatabase.mdb table-name | psql -d mypsqldatabase -U postgres -w -h localhost 

所以我一直在尝试编写一个Go命令程序来执行以下操作:

  1. 首先执行一个命令来列出表名,这将是下一个命令的参数。

  2. 然后开始循环执行一个命令,导出表数据,并将该命令的输出管道传递给下一个命令。

  3. 这个命令是psql,它将从前一个命令的输出中写入(即SQL插入语句)。

    package main

    import (
    "bufio"
    "log"
    "os"
    "os/exec"
    )
    func main() {
    // 命令用于收集表名并将其列出到下一个命令
    tablesname := exec.Command("mdb-tables", "-1", "myaccessdatabase.mdb")

     // 对每个表名运行命令,并将输出管道/输入传递给psql shell
     for _, table := range tablesname {
     	ls := exec.Command("mdb-export", "-I", "postgres", "-q", "'", "myaccessdatabase.mdb", table)
    
     	// | psql -d mydatabase -U postgres -w -h localhost 命令将从前一个命令的输出中写入每一行
     	visible := exec.Command("psql", "-d", "mypsqldatabase", "-U", "postgres", "-w", "-h", "localhost")
    
    
    
     }
    

    }

所以我尝试将输出导入到下一个命令的stdin中,但无法实现,同时我正在尝试使用goroutine和通道,但甚至无法找到一种将其转换为最后一个命令的方法。

非常感谢您的帮助。

英文:

I have eight Microsoft access databases each one has around 215 tables and I needed to transfered those databases into postgresql so i used mdb-tools and exported the schemes which just one step ;but when it come to exporting tables data into postgres directly into postgresql i have to write this command for every single table:

mdb-export -I postgres -q \' myaccessdatabase.mdb table-name | psql -d mypsqldatabase -U postgres -w -h localhost 

so I have been trying to write a go command program to do as follows:

  1. firstly excute a command to list tables name. which will be the arg of the next command.

  2. then start for range looop to excute a command that export tanle data and the output of this command is pipe into the next command.

  3. this command is psql which will write the output from the previous command ( which is sql insert statment)

    package main

    import (
    "bufio"
    "log"
    "os"
    "os/exec"
    )
    func main() {
    // command to Collect tables name and list it to the next command
    tablesname := exec.Command("mdb-tables", "-1", "myaccessdatabase.mdb")

     // Run the command on each table name and get the output pipe/feed into the psql shell 
     for _, table := range tablesname {
     	ls := exec.Command("mdb-export", "-I", "postgres", "-q", "\'", "myaccessdatabase.mdb", table)
    
     	// | psql -d mydatabase -U postgres -w -h localhost command which will write each line from the output of previouse command's 
     	visible := exec.Command("psql", "-d", "mypsqldatabase", "-U", "postgres", "-w", "-h", "localhost")
    
    
    
     }
    

    }

So i have tried to pipe the output into the stdin of the next command and couldn't implement it , meanwhile I am trying with goroutin and channels just been unable to even come with a way to make this into the last command.

Thank you very much in advance.

答案1

得分: 1

exec.Command函数只是创建命令,而不执行它。

要从tablesname := exec.Command("mdb-tables", "-1", "myaccessdatabase.mdb")获取输出,你需要运行该命令并捕获其输出:

tablesname := exec.Command("mdb-tables", "-1", "myaccessdatabase.mdb")
// 捕获命令的输出管道
outputStream := bufio.NewScanner(tablesname.StdoutPipe())
tablesname.Start()  // 在后台运行命令

for outputStream.Scan() {   
    // 默认的扫描器是逐行扫描,所以这将前进到下一行
    ls := exec.Command("mdb-export", "-I", "postgres", "-q", "'", "myaccessdatabase.mdb", outputStream.Text())
    ls.Run()  // 阻塞直到命令执行完成

    visible := exec.Command("psql", "-d", "mypsqldatabase", "-U", "postgres", "-w", "-h", "localhost")
    visible.Run()
}

tablesname.Wait()  // 清理

注意对于数据库交互使用`exec`不是惯用的代码

SQL库允许直接与数据库进行交互http://golang.org/pkg/database/sql/

<details>
<summary>英文:</summary>

The `exec.Command` function only creates the command, it doesn&#39;t execute it.  

To get the output from `tablesname := exec.Command(&quot;mdb-tables&quot;, &quot;-1&quot;, &quot;myaccessdatabase.mdb&quot;)`, you need to run the command and capture its output:

    tablesname := exec.Command(&quot;mdb-tables&quot;, &quot;-1&quot;, &quot;myaccessdatabase.mdb&quot;)
    //capture the output pipe of the command
    outputStream := bufio.NewScanner(tablesname.StdoutPipe())
    tablesname.Start()  //Runs the command in the background
    
    for outputStream.Scan() {   
    //Default scanner is a line-by-line scan, so this will advance to the next line
        ls := exec.Command(&quot;mdb-export&quot;, &quot;-I&quot;, &quot;postgres&quot;, &quot;-q&quot;, &quot;\&#39;&quot;, &quot;myaccessdatabase.mdb&quot;, outputStream.Text())
        ls.Run()  //Blocks until command finishes execution

        visible := exec.Command(&quot;psql&quot;, &quot;-d&quot;, &quot;mypsqldatabase&quot;, &quot;-U&quot;, &quot;postgres&quot;, &quot;-w&quot;, &quot;-h&quot;, &quot;localhost&quot;)
        visible.Run()
    }

    tablesname.Wait()  //Cleanup 

BEWARE:  For database interactions, `exec` isn&#39;t idiomatic code.  

The SQL library allows direct interaction with the database: http://golang.org/pkg/database/sql/

</details>



huangapple
  • 本文由 发表于 2015年9月19日 22:17:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/32669237.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定