英文:
os.exec.Command and pbcopy
问题
我正在尝试在Go中执行bash命令"hello world" | /usr/bin/pbcopy
:
package main
import (
"fmt"
"os/exec"
"strings"
)
func Cmd(cmd string) {
fmt.Println("command is ", cmd)
parts := strings.Fields(cmd)
head := parts[0]
parts = parts[1:len(parts)]
out, err := exec.Command(head, parts...).Output()
if err != nil {
fmt.Printf("%s", err)
}
fmt.Println("out")
fmt.Println(string(out))
}
func main() {
Cmd(`echo "hello world" | /usr/bin/pbcopy`)
}
当我运行这个go文件时,输出如下:
command is echo "hello world" | /usr/bin/pbcopy
out
"hello world" | /usr/bin/pbcopy
我期望剪贴板的内容应该是"hello world",但实际上并不是。
更新
我尝试使用io.Pipe
:
package main
import (
"bytes"
"io"
"os"
"os/exec"
)
func main() {
c1 := exec.Command(`echo "hello world"`)
c2 := exec.Command("/usr/bin/pbcopy")
r, w := io.Pipe()
c1.Stdout = w
c2.Stdin = r
var b2 bytes.Buffer
c2.Stdout = &b2
c1.Start()
c2.Start()
c1.Wait()
w.Close()
c2.Wait()
io.Copy(os.Stdout, &b2)
}
... 但剪贴板仍然不等于"hello world"。
英文:
I am trying to execute bash command "hello world" | /usr/bin/pbcopy
inside go:
package main
import (
"fmt"
"os/exec"
"strings"
)
func Cmd(cmd string) {
fmt.Println("command is ", cmd)
parts := strings.Fields(cmd)
head := parts[0]
parts = parts[1:len(parts)]
out, err := exec.Command(head, parts...).Output()
if err != nil {
fmt.Printf("%s", err)
}
fmt.Println("out")
fmt.Println(string(out))
}
func main() {
Cmd(`echo "hello world" | /usr/bin/pbcopy`)
}
When I run this go file, it outputs:
command is echo "hello world" | /usr/bin/pbcopy
out
"hello world" | /usr/bin/pbcopy
I expect clipboard to be equal to "hello world" but it is not.
Update
I've tried to use io.Pipe
package main
import (
"bytes"
"io"
"os"
"os/exec"
)
func main() {
c1 := exec.Command(`echo "hello world"`)
c2 := exec.Command("/usr/bin/pbcopy")
r, w := io.Pipe()
c1.Stdout = w
c2.Stdin = r
var b2 bytes.Buffer
c2.Stdout = &b2
c1.Start()
c2.Start()
c1.Wait()
w.Close()
c2.Wait()
io.Copy(os.Stdout, &b2)
}
... but clipboard is still not equal to "hello world"
答案1
得分: 2
Command
函数接受一个可执行文件和一个参数列表。所以当你调用:
exec.Command(`echo "hello world"`)
这实际上是尝试运行一个名为echo "hello world"
的命令(包括空格和引号)。正如你已经了解的那样,exec.Command
不会将内容传递给shell,所以使用"|"这样的管道符号也不会起作用。如果你想将标准输出和标准输入连接在一起,代码如下:
func main() {
c1 := exec.Command("echo", "hello world")
c2 := exec.Command("/usr/bin/pbcopy")
c1stdout, _ := c1.StdoutPipe()
c2stdin, _ := c2.StdinPipe()
c1.Start()
c2.Start()
io.Copy(c2stdin, c1stdout)
c2stdin.Close()
c2.Wait()
}
但其实没有必要这么麻烦。你有一个shell,如果你要求它,它可以为你完成所有这些操作。
func main() {
exec.Command("sh", "-c", `echo "hello world" | pbcopy`).Run()
}
英文:
Command
takes an executable and a list of arguments. So when you call
exec.Command(`echo "hello world"`)
That literally tries to run a command called echo "hello world"
(with space and quotes). As you've already learned, exec.Command
does not pass things to the shell, so "|" won't work either this way. So if you're going to piece it all together by tying the stdout and stdin together, it would look like this:
func main() {
c1 := exec.Command("echo", "hello world")
c2 := exec.Command("/usr/bin/pbcopy")
c1stdout, _ := c1.StdoutPipe()
c2stdin, _ := c2.StdinPipe()
c1.Start()
c2.Start()
io.Copy(c2stdin, c1stdout)
c2stdin.Close()
c2.Wait()
}
But there's no need for all that. You have a shell. It can do all of this for you if you ask it to.
func main() {
exec.Command("sh", "-c", `echo "hello world" | pbcopy`).Run()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论