实现命令行解释器
本文关键字:解释器 命令行 实现 | 更新日期: 2023-09-27 18:11:42
在terminal或cmd中,您可以编写命令,其中有一个主命令,然后是子命令,或参数和东西…这样的:
cd Desktop'Folder
lst
Format E: /fs:FAT32
我想创建一个c#控制台应用程序,它可以执行像这样的预定义命令,但它也可以分割主命令和子命令,其中有些可以是可选的,有些则不是。我试过把所有作为字符串,然后把它分割成数组,创建if(s)
和switch
和case
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
这是一个类似于CMD或Bash的命令解释器。我们在MIT许可下发布了它,这是一个带有c#()一些功能的shell。网络核心)。如果你愿意,你可以贡献 GitHub。
为了解决给定令牌(命令行的一部分)与内置命令或命令的匹配问题,我们使用字典。
但是,我们暂时不索引路径中的程序。我们只需将程序名与%PATH%
变量中的所有路径结合起来。
- 捕获输入
- 展开环境变量,展开别名
- 尝试匹配一个内置程序并运行它,如果有匹配
- 尝试与
%PATH%
/$PATH
中的程序匹配 - 运行程序或显示错误
虽然您不太可能找到CMD的内部工作(因为它是闭源的),但您可以轻松找到unix shell (bash, sh, zsh等)信息。
链接:
Bash参考
Zsh参考
TCSH参考