英文:
How wrap a command that is interactive
问题
我正在构建一个在生成之前执行一些操作的FTP包装器,我可以很容易地用shell脚本来实现,但我想知道如何在Go语言中实现。
对于简单的命令,可以使用exec.Command。
out, err := exec.Command("ls").Output() // 可行
但是,如何包装交互式命令,比如ftp呢?
out, err := exec.Command("ftp").Output()
它只是退出了。如何处理标准输入?
例如,bash的等效方式:
> ./t.sh
欢迎来到myftp
ftp> open blahblah.com
> cat t.sh
#!/bin/bash
echo "欢迎来到myftp"
#其他命令,如auth/authoriz等
shift
echo "$@"
ftp
C++的等效方式:
int main() {
system("ftp");
return 0;
}
英文:
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.
out, err := exec.Command("ls").Output() // Works
How do I wrap commands that are interactive e.g., ftp
out, err := exec.Command("ftp").Output()
It just exits. How do I deal with stdin ?
e.g., bash equivalent :
> ./t.sh
Welcome to myftp
ftp> open blahblah.com
> cat t.sh
#!/bin/bash
echo "Welcome to myftp "
#extra commands such as auth/authoriz.. etc.,
shift
echo "$@"
ftp
c++ equivalent :
int main() {
system("ftp");
return 0;
}
答案1
得分: 3
我会做一些类似这样的事情,更本地化,不涉及外部包。
package main
import (
"os"
"os/exec"
)
func main() {
cmd := exec.Command("ls")
// 将输出重定向到终端
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
}
英文:
I would probably do something like this which is more native and doesn't involve an external package
package main
import (
"os"
"os/exec"
)
func main() {
cmd := exec.Command("ls")
// redirect the output to terminal
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
}
答案2
得分: 1
传统上,这种交互式脚本练习最好使用expect来完成。我可以建议你查看一个纯Go的等效工具。
从自述文件中可以看到:
child, err := gexpect.Spawn("python")
if err != nil { panic(err) }
child.Expect(">>>")
child.SendLine("print 'Hello World'")
child.Interact()
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:
child, err := gexpect.Spawn("python")
if err != nil { panic(err) }
child.Expect(">>>")
child.SendLine("print 'Hello World'")
child.Interact()
child.Close()
答案3
得分: 0
运行任何需要提示用户输入的命令:
cmd := exec.Command("cf", "login")
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Run()
英文:
To run any commands which will prompt for user input:
cmd := exec.Command("cf", "login")
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Run()
答案4
得分: 0
可以使用以下完整脚本来“包装”一个命令,该脚本基于reticentroot的答案和这个答案关于获取exec命令返回代码(go 1.12+):
package main
import (
"os"
"os/exec"
)
var (
bin = "py"
args = []string{"-3.8"}
)
func main() {
cmd := exec.Command(bin, append(args, os.Args[1:]...)...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
if err := cmd.Run(); err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
os.Exit(exitError.ExitCode())
}
}
}
希望对你有帮助!
英文:
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+):
package main
import (
"os"
"os/exec"
)
var (
bin = "py"
args = []string{"-3.8"}
)
func main() {
cmd := exec.Command(bin, append(args, os.Args[1:]...)...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
if err := cmd.Run() ; err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
os.Exit(exitError.ExitCode())
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论