实现命令行解释器

本文关键字:解释器 命令行 实现 | 更新日期: 2023-09-27 18:11:42

在terminal或cmd中,您可以编写命令,其中有一个主命令,然后是子命令,或参数和东西…这样的:

cd Desktop'Folder
lst
Format E: /fs:FAT32

我想创建一个c#控制台应用程序,它可以执行像这样的预定义命令,但它也可以分割主命令和子命令,其中有些可以是可选的,有些则不是。我试过把所有作为字符串,然后把它分割成数组,创建if(s)switchcase s,但它看起来真的很糟糕,很难管理。我确信在操作系统的终端或cmd中,它是以另一种方式构建的。你能帮我了解一下这样一个应用程序的基本结构吗?

实现命令行解释器

来,看看这个概念。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SharpConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Welcome to SharpConsole. Type in a command.");
            while (true)
            {
                Console.Write("$ ");
                string command = Console.ReadLine();
                string command_main = command.Split(new char[] { ' ' }).First();
                string[] arguments = command.Split(new char[] { ' ' }).Skip(1).ToArray();
                if (lCommands.ContainsKey(command_main))
                {
                    Action<string[]> function_to_execute = null;
                    lCommands.TryGetValue(command_main, out function_to_execute);
                    function_to_execute(arguments);
                }
                else
                    Console.WriteLine("Command '" + command_main + "' not found");
            }
        }
        private static Dictionary<string, Action<string[]>> lCommands = 
            new Dictionary<string, Action<string[]>>()
            {
                { "help", HelpFunc },
                { "cp" , CopyFunc }
            };
        private static void CopyFunc(string[] obj)
        {
            if (obj.Length != 2) return;
            Console.WriteLine("Copying " + obj[0] + " to " + obj[1]);
        }
        public static void HelpFunc(string[] args)
        {
            Console.WriteLine("===== SOME MEANINGFULL HELP ==== ");
        }
    }
}

基本思想是概括命令的思想。我们有一个Dictionary,其中键是一个字符串(命令的名称),您从字典中获得的值是一个类型为Action<string[]>函数。任何具有void Function(string[])签名的函数都可以作为此类型使用。然后,您可以用一堆命令设置这个字典,并将它们路由到您想要的函数。这些函数中的每一个都将接收一个可选参数数组。因此,命令"help"将被路由到HelpFunc()。例如,"cp"命令将接收一个文件名数组。命令的解析总是相同的。我们读一行,把它分开。第一个字符串是程序名,这里是command_main。如果您跳过第一个字符串,您将得到您键入的所有其他子命令或开关的枚举。然后,在字典中进行查找,以查看是否存在这样的命令。如果是,我们获取函数并带参数执行它。如果没有,您应该显示"未找到命令"或其他内容。总而言之,这个练习可以简化为在可能的命令字符串字典中查找函数,然后执行它。所以可能的输出是

Welcome to SharpConsole. Type in a command. 
$ help
===== SOME MEANINGFULL HELP ==== 
$ cp file1 otherfile2 
Copying file1 to otherfile2 
$ python --version
Command 'python' not found
$ ...

LXSH

这是一个类似于CMDBash的命令解释器。我们在MIT许可下发布了它,这是一个带有c#()一些功能的shell。网络核心)。如果你愿意,你可以贡献 GitHub。

为了解决给定令牌(命令行的一部分)与内置命令或命令的匹配问题,我们使用字典。

但是,我们暂时不索引路径中的程序。我们只需将程序名与%PATH%变量中的所有路径结合起来。

  1. 捕获输入
  2. 展开环境变量,展开别名
  3. 尝试匹配一个内置程序并运行它,如果有匹配
  4. 尝试与%PATH%/$PATH中的程序匹配
  5. 运行程序或显示错误

虽然您不太可能找到CMD的内部工作(因为它是闭源的),但您可以轻松找到unix shell (bash, sh, zsh等)信息。

链接:

Bash参考
Zsh参考
TCSH参考