英文:
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命令程序来执行以下操作:
-
首先执行一个命令来列出表名,这将是下一个命令的参数。
-
然后开始循环执行一个命令,导出表数据,并将该命令的输出管道传递给下一个命令。
-
这个命令是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:
-
firstly excute a command to list tables name. which will be the arg of the next command.
-
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.
-
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't execute it.
To get the output from `tablesname := exec.Command("mdb-tables", "-1", "myaccessdatabase.mdb")`, you need to run the command and capture its output:
tablesname := exec.Command("mdb-tables", "-1", "myaccessdatabase.mdb")
//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("mdb-export", "-I", "postgres", "-q", "\'", "myaccessdatabase.mdb", outputStream.Text())
ls.Run() //Blocks until command finishes execution
visible := exec.Command("psql", "-d", "mypsqldatabase", "-U", "postgres", "-w", "-h", "localhost")
visible.Run()
}
tablesname.Wait() //Cleanup
BEWARE: For database interactions, `exec` isn't idiomatic code.
The SQL library allows direct interaction with the database: http://golang.org/pkg/database/sql/
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论