• 2. 处理脚本命令行参数


    一旦你的脚本开始变得更加高级,你就会想利用这个参数来让你的脚本执行多种操作。例如,如果你在写一个气闸脚本,你会想告诉脚本让一个气闸循环进出,甚至让哪个气闸循环。我不会告诉你如何写一个气闸脚本,但我将以此为例,向你展示如何检测和处理与这种脚本有关的参数。可编程块API有一个内置的命令行解析器,这是由你提供的,它被设计成快速和分配友好,以及易于使用。

    对于那些只想继续使用它的人,这里是本教程中使用的简单演示脚本的链接。气闸门

    1. MyCommandLine

    这段代码初始化了命令行解析器,并试图解析传入的参数。如果它找到了参数,TryParse方法将返回true

    MyCommandLine _commandLine = new MyCommandLine();
    
    public void Main(string argument)
    {
        if (_commandLine.TryParse(argument)) {
            // The command line parser found arguments in the string.
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2. The Argument Formats

    传统的命令行中包含了argumentswitch

    cycle "Airlock 1" in -emergency
    
    • 1

    (1) argument

    argument: 是以空格为间隔的字符串(cycle)或("Airlock 1")字符串。当argument串有空格分开的过个单词组成,需要用引号概括。
    argument的访问和数组一样,通过位置访问元素。第一个元素下标是0,依此类推。
    
    • 1
    • 2

    (2) switch

    格式: -emergency
    访问:switches放置在任何地方都行,不通过位置访问。

    (3) 例子

    eg1和eg2显示,放置 -emergency 开关的位置无关紧要,它不会影响参数的索引。

    cycle "Airlock 1" in -emergency  #eg1
    -emergency cycle "Airlock 1" in   # eg2
    
    • 1
    • 2
    • eg1:
      arguments:
    0: cycle
    1: "Airclock 1"
    2: in
    
    • 1
    • 2
    • 3

    switch:

    -emergency
    
    • 1
    • eg2:
      arguments:
    0: cycle
    1: "Airclock 1"
    2: in
    
    • 1
    • 2
    • 3

    switch:

    -emergency
    
    • 1

    3、arguments和switches的解析

    MyCommandLine类提供方法:Switch(name),获取名字为name的switch的参数。

    (1) MyCommandLine::Switch(strname)

    // check if the -myflag switch is set
    bool switchIsSet = _commandLine.Switch("myflag");
    
    • 1
    • 2

    (2) MyCommandLine::Arguments(idx)

    // retrieve the first argument of the string (either a word or a "quoted string"). The quotes are removed for you.
    string arg = _commandLine.Argument(0);
    
    • 1
    • 2

    (3) 命令和参数绑定

    首先,我们将需要一种方法来区分命令。第一个参数,当然,将是命令指示器。我们将创建一个字典来保存这些命令。

    Dictionary _commands = new Dictionary(StringComparer.OrdinalIgnoreCase);
    
    • 1

    注意,我们传入了一个不区分大小写的字符串比较器,所以我们可以接受CYCLE以及cycle。接下来我们需要初始化这些命令。这一点我们在脚本构造函数中完成。

    • _commands字典,绑定arguments和action
    //_commands字典,绑定arguments和action
    public Program() 
    {
        // Associate the Cycle method with the cycle command
        _commands["cycle"] = Cycle;
    }
    
    public void Cycle()
    {
    	// This method will hold the code to perform the desired action
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 编辑Main方法来使用这个字典来选择和执行命令。
    public void Main(string argument)
    {
    	// 解析命令行参数
        if (_commandLine.TryParse(argument))
        {
            Action commandAction;
    
            // Retrieve the first argument. Switches are ignored.
            string command = _commandLine.Argument(0);
    
            // Now we must validate that the first argument is actually specified, 
            // then attempt to find the matching command delegate.
            if (command == null)
            {
                Echo("No command specified");
            } 
            else if (_commands.TryGetValue(command, out commandAction))
            {
                ///< 在Programs()中绑定了"cycle"字符串和函数Cycle()
                ///< 从字典_commands中取出"cycle"对应的Action执行
                commandAction();
            }
            else
            {
                Echo($"Unknown command {command}");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 最后,我们必须在与cycle命令相关的Cycle方法中完成对命令特定参数的处理。
    public void Cycle()
    {
        //解析switch参数emergency
        bool emergencyCycle = _commandLine.Switch("emergency");
    
        //命令行中解析气闸门的名字,用于cycle。这里index=1。没有气闸门就退出
        string airlockName = _commandLine.Argument(1);
        if (airlockName == null)
        {
            Echo("Cannot cycle, no airlock specified");
            return;
        }
    
        // Argument no. 2 should be either "in" or "out", indicating
        // which direction to cycle
        ///< 命令行中读取index=2的参数,确定进出方向in/out
        string direction = _commandLine.Argument(2);
        if (direction == null)
        {
            Echo($"Cannot cycle {airlockName}, no direction specified");
            return;
        }
        if (string.Equals(direction, "in", StringComparison.OrdinalIgnoreCase))
        {
            Echo($"Cycling airlock {airlockName} in...");
            // TODO: Begin the cycling of the airlock
        }
        else if (string.Equals(direction, "out", StringComparison.OrdinalIgnoreCase))
        {
            Echo($"Cycling airlock {airlockName} out...");
            // TODO: Begin the cycling of the airlock
        }
        else
        {
            // The argument was none of the expected values
            Echo($"Cannot cycle {airlockName}, cannot understand direction {direction}");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    4. code example

    MyCommandLine _commandLine = new MyCommandLine();
    Dictionary _commands = new Dictionary(StringComparer.OrdinalIgnoreCase);
    
    public Program()
    {
        _commands["cycle"] = Cycle;
    }
    
    public void Cycle()
    {
        // Check if the "emergency" switch is set.
        bool emergencyCycle = _commandLine.Switch("emergency");
    
        // Argument no. 1 is the name of the airlock to cycle
        string airlockName = _commandLine.Argument(1);
        if (airlockName == null)
        {
            Echo("Cannot cycle, no airlock specified");
            return;
        }
    
        // Argument no. 2 should be either "in" or "out", indicating
        // which direction to cycle
        string direction = _commandLine.Argument(2);
        if (direction == null)
        {
            Echo($"Cannot cycle {airlockName}, no direction specified");
            return;
        }
    
        if (string.Equals(direction, "in", StringComparison.OrdinalIgnoreCase))
        {
            Echo($"Cycling airlock {airlockName} in...");
            // TODO: Begin the cycling of the airlock
        }
        else if (string.Equals(direction, "out", StringComparison.OrdinalIgnoreCase))
        {
            Echo($"Cycling airlock {airlockName} out...");
            // TODO: Begin the cycling of the airlock
        }
        else
        {
            // The argument was none of the expected values
            Echo($"Cannot cycle {airlockName}, cannot understand direction {direction}");
        }
    }
    
    public void Main(string argument)
    {
        if (_commandLine.TryParse(argument))
        {
            Action commandAction;
    
            // Retrieve the first argument. Switches are ignored.
            string command = _commandLine.Argument(0);
    
            // Now we must validate that the first argument is actually specified, 
            // then attempt to find the matching command delegate.
            if (command == null)
            {
                Echo("No command specified");
            }
            else if (_commands.TryGetValue(_commandLine.Argument(0), out commandAction))
            {
                // We have found a command. Invoke it.
                commandAction();
            }
            else
            {
                Echo($"Unknown command {command}");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
  • 相关阅读:
    笔试强训Day14&&Day15
    企业数字化成功转型的关键,从这三方面出发
    平衡树之B树
    JavaScript基础 JavaScript第二天 2. 语句
    YOLOv8学习
    JSP out.println()方法具有什么功能呢?
    内核网络接口层的实现
    解锁各种js数组骚操作,总有你想要的!
    java服务器如何知道客户端请求的ip地址
    【小程序从0到1】小程序常用组件一览
  • 原文地址:https://blog.csdn.net/qq_34942306/article/details/127735796