如何包装一个交互式的命令?

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

How wrap a command that is interactive

问题

我正在构建一个在生成之前执行一些操作的FTP包装器,我可以很容易地用shell脚本来实现,但我想知道如何在Go语言中实现。

对于简单的命令,可以使用exec.Command。

  1. out, err := exec.Command("ls").Output() // 可行

但是,如何包装交互式命令,比如ftp呢?

  1. out, err := exec.Command("ftp").Output()

它只是退出了。如何处理标准输入?

例如,bash的等效方式:

  1. > ./t.sh
  2. 欢迎来到myftp
  3. ftp> open blahblah.com
  4. > cat t.sh
  5. #!/bin/bash
  6. echo "欢迎来到myftp"
  7. #其他命令,如auth/authoriz等
  8. shift
  9. echo "$@"
  10. ftp

C++的等效方式:

  1. int main() {
  2. system("ftp");
  3. return 0;
  4. }
英文:

I am building an ftp wrapper that does some stuff before I spawn, I could easily do it in a shell script but wondering how I could do it in go

While exec.Command works for simple commands.

  1. out, err := exec.Command("ls").Output() // Works

How do I wrap commands that are interactive e.g., ftp

  1. out, err := exec.Command("ftp").Output()

It just exits. How do I deal with stdin ?

e.g., bash equivalent :

  1. > ./t.sh
  2. Welcome to myftp
  3. ftp> open blahblah.com
  4. > cat t.sh
  5. #!/bin/bash
  6. echo "Welcome to myftp "
  7. #extra commands such as auth/authoriz.. etc.,
  8. shift
  9. echo "$@"
  10. ftp

c++ equivalent :

  1. int main() {
  2. system("ftp");
  3. return 0;
  4. }

答案1

得分: 3

我会做一些类似这样的事情,更本地化,不涉及外部包。

  1. package main
  2. import (
  3. "os"
  4. "os/exec"
  5. )
  6. func main() {
  7. cmd := exec.Command("ls")
  8. // 将输出重定向到终端
  9. cmd.Stdout = os.Stdout
  10. cmd.Stderr = os.Stderr
  11. cmd.Run()
  12. }
英文:

I would probably do something like this which is more native and doesn't involve an external package

  1. package main
  2. import (
  3. "os"
  4. "os/exec"
  5. )
  6. func main() {
  7. cmd := exec.Command("ls")
  8. // redirect the output to terminal
  9. cmd.Stdout = os.Stdout
  10. cmd.Stderr = os.Stderr
  11. cmd.Run()
  12. }

答案2

得分: 1

传统上,这种交互式脚本练习最好使用expect来完成。我可以建议你查看一个纯Go的等效工具

从自述文件中可以看到:

  1. child, err := gexpect.Spawn("python")
  2. if err != nil { panic(err) }
  3. child.Expect(">>>")
  4. child.SendLine("print 'Hello World'")
  5. child.Interact()
  6. child.Close()
英文:

Traditionally these sorts of interactive scripting exercises are best done with expect. May I suggest checking out a pure Go equivalent?

From the readme:

  1. child, err := gexpect.Spawn("python")
  2. if err != nil { panic(err) }
  3. child.Expect(">>>")
  4. child.SendLine("print 'Hello World'")
  5. child.Interact()
  6. child.Close()

答案3

得分: 0

运行任何需要提示用户输入的命令:

  1. cmd := exec.Command("cf", "login")
  2. cmd.Stdout = os.Stdout
  3. cmd.Stdin = os.Stdin
  4. cmd.Run()
英文:

To run any commands which will prompt for user input:

  1. cmd := exec.Command("cf", "login")
  2. cmd.Stdout = os.Stdout
  3. cmd.Stdin = os.Stdin
  4. cmd.Run()

答案4

得分: 0

可以使用以下完整脚本来“包装”一个命令,该脚本基于reticentroot的答案这个答案关于获取exec命令返回代码(go 1.12+):

  1. package main
  2. import (
  3. "os"
  4. "os/exec"
  5. )
  6. var (
  7. bin = "py"
  8. args = []string{"-3.8"}
  9. )
  10. func main() {
  11. cmd := exec.Command(bin, append(args, os.Args[1:]...)...)
  12. cmd.Stdout = os.Stdout
  13. cmd.Stderr = os.Stderr
  14. cmd.Stdin = os.Stdin
  15. if err := cmd.Run(); err != nil {
  16. if exitError, ok := err.(*exec.ExitError); ok {
  17. os.Exit(exitError.ExitCode())
  18. }
  19. }
  20. }

希望对你有帮助!

英文:

A command can be "wrapped" using the following complete script, based on reticentroot's answer and this answer regarding obtaining exec command return codes (go 1.12+):

  1. package main
  2. import (
  3. "os"
  4. "os/exec"
  5. )
  6. var (
  7. bin = "py"
  8. args = []string{"-3.8"}
  9. )
  10. func main() {
  11. cmd := exec.Command(bin, append(args, os.Args[1:]...)...)
  12. cmd.Stdout = os.Stdout
  13. cmd.Stderr = os.Stderr
  14. cmd.Stdin = os.Stdin
  15. if err := cmd.Run() ; err != nil {
  16. if exitError, ok := err.(*exec.ExitError); ok {
  17. os.Exit(exitError.ExitCode())
  18. }
  19. }
  20. }

huangapple
  • 本文由 发表于 2016年9月28日 06:15:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/39735171.html
匿名

发表评论

匿名网友

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

确定