golang shell_今天我学会了:在Golang中制作一个简单的交互式Shell应用程序

本文介绍了如何在Golang中不依赖外部库,制作一个简单的交互式Shell应用程序。作者通过读取终端输入,执行命令,处理参数,添加无限循环,实现命令的执行和自定义命令的添加,从而构建了一个基础的CLI应用。
摘要由CSDN通过智能技术生成

golang shell

我如何在Golang中制作一个简单的交互式外壳

Hannah Joshua在“ Unsplash ”上发表的 “命令计算机键盘键”

所以今天,我在Golang学习了一些新知识和一些基础知识。 它正在制作一个简单的交互式外壳。 这只是一个非常简单的应用程序,但制作起来看起来很酷。

我在Golang工作了1年以上。 人们已经创建了这么多工具,例如: spf13创建的cobra或更多有助于我们制作命令行应用程序的工具。 但是,以某种方式,我很好奇如何在不依赖其他外部库的情况下制作一个简单的库。

因此,出于好奇,我开始搜索如何在Google中进行制作。 但是我发现只有使用其他外部依赖项的教程。 每个人都只是在推广自己的库以简化制作交互式shell的过程。 伙计们? 我只需要使用纯Golang包(没有外部依赖项)来制作一个简单的😌

但是,我发现了一篇有关制作交互式外壳的文章,例如这篇文章: http : //technosophos.com/2014/07/11/start-an-interactive-shell-from-within-go.html ,但是,他确实不像我想要的。 因此,以后只提供了我在Gobyexample.com等网站上发现的许多示例。

我自己编写了一个简单的Shell应用程序。 在这里,我将在下面说明如何做到这一点。

贝壳

因此,在制作简单的Shell应用程序之前,我想确保Shell的含义与您的含义相同。

对我来说,Shell是一个将充当非常基本的用户界面(基于文本的界面)的应用程序。 有人可能会说它是命令行界面(CLI)。

申请

为了制作应用程序,对于最简单的原型,我将像这样制作。

$ls <br> go . mod  main. go

从终端读取命令

为此,首先要做的就是读取输入。 我需要从终端读取输入。 为此,我做到了。

reader := bufio.NewReader(os.Stdin)
cmdString,err := reader.ReadString( '\n' )
if err != nil {
 fmt.Fprintln(os.Stderr, err)
}

执行命令

然后执行命令。 从终端读取命令字符串后,现在执行命令。

cmdString = strings.TrimSuffix(cmdString,"\n" )
cmd := exec.Command(commandString)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Run()

到这里为止,现在我可以运行我的简单shell应用程序,但是它将仅运行一个命令。 运行命令后,它将停止。

添加无限循环

使它在执行一次后接收所有命令。 我们需要将其添加到无限循环中。

for {
 fmt.Print( "$ " )
 cmdString, err := reader.ReadString( '\n' )
 if err != nil {
  fmt.Fprintln(os.Stderr, err)
 }
cmdString = strings.TrimSuffix(cmdString, "\n" )
cmd := exec.Command(cmdString)
 cmd.Stderr = os.Stderr
 cmd.Stdout = os.Stdout
 err = cmd.Run()
 if err != nil {
  fmt.Fprintln(os.Stderr, err)
 }
}

如果我们运行该应用程序,它将如下所示

简单的外壳程序

处理论点

在这一行之前,我已经完成了我的第一个CLI应用程序。 但是它仍然不接受参数。 如果我传递参数,那么它将引发错误。

$ls -lah // this command wil throw error

要阅读这些参数,请在下面进行说明。 首先,我将命令拆分为字符串数组。

// ...
cmdString = strings.TrimSuffix(cmdString, "\n" )
arrCommandStr := strings.Fields(cmdString)
cmd := exec.Command(arrCommandStr[ 0 ], arrCommandStr[ 1 :]...)
// ...

为了拆分文本,我使用了包字符串中的Fields函数。 此功能类似于分割字符串功能。 如果是string.Split,则将使用给定的特定分隔符拆分字符串。 但是字符串。字段将用空格分隔单词。

例:

str :="Hello World    Beautiful World"
arrString := strings.Fields(str)
fmt.Println(arrString)
// [Hello World Beautiful World]

现在,我的简单外壳程序已经接受并处理给定的参数。 现在,该命令应该起作用了。

$ ls -lah
total4280
drwxr-xr-x  5 iman  staff   160 B Nov  6 19 : 48 .
drwxr-xr-x  6 iman  staff   192 B Nov  6 11 : 41 ..
-rw-r--r--  1 iman  staff    38 B Nov  6 11 : 43 go.mod
-rw-r--r--  1 iman  staff   606 B Nov  6 20 : 11 main.go
-rwxr-xr-x  1 iman  staff   2.1 M Nov  6 19 : 49 simshel

添加退出命令

但是,此应用程序仅适用于在环境中注册的任何内置应用程序。 像退出之类的命令不存在,因为它已在每个CLI应用程序中编程。

然后,我为系统中没有内置应用程序的每个命令(如exit命令)创建一个切换案例处理程序。

package mainimport (
	"bufio"
	"fmt"
	"os"
	"os/exec"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	for {
		fmt.Print( "$ " )
		cmdString, err := reader.ReadString( '\n' )
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
		}
		err = runCommand(cmdString)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
		}
	}
}
func runCommand(commandStr string) error {
	commandStr = strings.TrimSuffix(commandStr, "\n" )
	arrCommandStr := strings.Fields(commandStr)
	switch arrCommandStr[ 0 ] {
	case "exit" :
		os.Exit( 0 )
		// add another case here for custom commands.
	}
	cmd := exec.Command(arrCommandStr[ 0 ], arrCommandStr[ 1 :]...)
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

添加自定义命令

要添加自定义命令,我可以简单地将其添加到切换案例处理程序中。 例如,我想添加类似plus的命令。 此命令在任何CLI应用程序中都不存在。 我想要这样:

$ plus2 4 5 6 <br> 17

为此,我只需要添加一个sum函数并在switch-case中添加命令case处理程序

结论

最后,它只是一个非常简单的应用程序。 但是可以肯定的是,我在做这个时学到了一些东西。 而且,在撰写本文时,我发现了与此文章类似的文章(这里: https//sj14.gitlab.io/post/2018-07-01-go-unix-shell/ )。 阅读该文章后,我正在考虑放弃我的草稿。 但是,我在这里写了很多解释和示例,所以无论如何我决定将其发布为XD。

无论如何,我也将源代码也放在了我的Github中: https : //github.com/bxcodec/simpleshell ,如果碰巧的话,我稍后会尝试在其中添加一些功能。

*印尼文版本: https//medium.com/easyread/today-i-learned-belajar-membuat-aplikasi-interactive-shell-sederhana-di-golang-2ef013003393
*更新:添加了另一个自定义命令示例

翻译自: https://hackernoon.com/today-i-learned-making-a-simple-interactive-shell-application-in-golang-aa83adcb266a

golang shell

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值