Early leader to make your own shell with a CMD module

by SkillAiNest

Early leader to make your own shell with a CMD moduleEarly leader to make your own shell with a CMD module
Photo by Author | Ideogram

. Introduction

I am sure that most of you have used a command shell at some point. If you do not have, while it may look boring compared to GUI, the command line interface (CLI) is very lightweight and provides you with a lot of control. Some common examples are scallets, guts, and Azigar Republics. In this tutorial, we will learn how to use Uzar cmd Module for building our own interactive shell without any external dependence. Starting is very easy and intuitive. Working on such projects helps you understand that you usually use every day but don’t think much about it. It is also useful if you ever intend to create an admin console for your applications.

We will build our shell in small parts, start with a minimal example and then gradually add commands, help, basic verification, nickname, and friendly output. The only requirement from you is to be basic familiarity with the functions and classes. So, let’s start.

. Phased action to build your own Azgar Shell

Let’s take a quick review of it cmd The module, since we have already used it but has not explained what it is. It provides a base class (cmd.Cmd) To build Line -based command spokespersonWhich means it takes action on a command at a time. It also takes care of reading input through a prompt, command dispatch (methods) and help system. You impose commands by explaining the designated methods do_. The module handles the rest – easy and easy.

!! Step 1: Making a minimum shell

Create a file that says myshell.py:

import cmd

class MyShell(cmd.Cmd):
    intro = "Welcome to MyShell! Type help or ? to list commands.\n"
    prompt = "(myshell) "

    def do_greet(self, arg):
        """Greet the named person: greet """
        name = arg.strip() or "stranger"
        print(f"Hello, {name}!")

    def do_exit(self, arg):
        """Exit the shell."""
        print("Goodbye!")
        return True  # Returning True tells cmdloop() to exit

if __name__ == "__main__":
    MyShell().cmdloop()

Run using the code:

Now, let’s try some orders. cmdloop() The interactive loop will start, and we will be able to discuss the following:

Welcome to MyShell! Type help or ? to list commands.
(myshell) help

Documented commands (type help ):
========================================
exit  greet  help

(myshell) ?
Documented commands (type help ):
========================================
exit  greet  help

(myshell) greet kanwal
Hello, kanwal!

(myshell) exit
Goodbye!

!! Step 2: Clear the arguments

There are more complex orders that require a number of input values. Its l’e, we’ll use shlex.split. Let’s take a look at the example code:

import cmd
import shlex

class MyShell(cmd.Cmd):
    intro = "Welcome to MyShell! Type help or ? to list commands.\n"
    prompt = "(myshell) "

    def do_add(self, arg):
        """Add numbers: add 1 2 3"""
        try:
            parts = shlex.split(arg)
            nums = (float(p) for p in parts)
        except ValueError:
            print("Error: all arguments must be numbers.")
            return
        except Exception as e:
            print(f"Parse error: {e}")
            return

        total = sum(nums)
        print(f"Sum = {total}")

    def do_exit(self, arg):
        """Exit the shell."""
        print("Goodbye!")
        return True

if __name__ == "__main__":
    MyShell().cmdloop()

Now, let’s try it:

Welcome to MyShell! Type help or ? to list commands.

(myshell) ?
Documented commands (type help ):
========================================
add  exit  help

(myshell) add 2450 3456 8904 3467 
Sum = 18277.0

(myshell) exit
Goodbye!

!! Step 3: Adding help system

We have already seen a help command. This is pre -default cmd The module automatically creates. This shows the procedure. You can also add customized support of the command or such title l

class MyShell(cmd.Cmd):
    intro = "Welcome to MyShell! Type help or ? to list commands.\n"
    prompt = "(myshell) "

    def do_greet(self, arg):
        """Greet someone. Usage: greet """
        name = arg.strip() or "stranger"
        print(f"Hello, {name}!")

    def help_greet(self):
        print("greet ")
        print("  Prints a friendly greeting.")
        print("  Example: greet Alice")

    def do_exit(self, arg):
        """Exit the shell."""
        print("Goodbye!")
        return True

    def do_help(self, arg):
        # Keep default behavior, but show a tiny guide when no arg
        if arg:
            return super().do_help(arg)
        super().do_help(arg)
        print()
        print("Basics:")
        print("  - Use 'help' or '?' to list commands.")
        print("  - Use 'help ' for details.")
        print("  - Arguments support quotes (via shlex).")
Welcome to MyShell! Type help or ? to list commands.

(myshell) help
Documented commands (type help ):
========================================
exit  greet
Undocumented commands:
======================
help
Basics:
  - Use 'help' or '?' to list commands.
  - Use 'help ' for details.
  - Arguments support quotes (via shlex).
  
(myshell) help greet
greet 
  Prints a friendly greeting.
  Example: greet Alice
  
(myshell) help exit
Exit the shell.

(myshell) exit
Goodbye!

!! Step 4: To deal with errors and unknown orders

We can overwride default() How to stop unknown orders. You can also use emptyline() When pressing the user, they enter without input to control what happens. Let’s do nothing to the shell if no input has been entered:

class MyShell(cmd.Cmd):
    prompt = "(myshell) "

    def default(self, line):
        print(f"Unknown command: {line!r}. Type 'help' to list commands.")

    def emptyline(self):
        # By default, pressing Enter repeats the last command. Override to do nothing.
        pass

    def do_exit(self, arg):
        """Exit the shell."""
        print("Goodbye!")
        return True
(myshell) help

Documented commands (type help ):
========================================
exit  help

(myshell) 
(myshell) 
(myshell) exit
Goodbye!

!! Step 5: Adding command nickname

Arafat is a short name. Many of my friends also have nicknames, especially the same names. Likewise, you can use a little and easily to remember. precmd() The method is how you can do this:

import shlex
import cmd

class MyShell(cmd.Cmd):
    prompt = "(myshell) "
    aliases = {
        "quit": "exit",
        "q": "exit",
        "hello": "greet",
        "sum": "add",
    }

    def precmd(self, line: str) -> str:
        # Normalize/massage input before dispatch
        parts = line.strip().split(maxsplit=1)
        if not parts:
            return line
        cmd_name = parts(0)
        rest = parts(1) if len(parts) > 1 else ""
        if cmd_name in self.aliases:
            cmd_name = self.aliases(cmd_name)
        return f"{cmd_name} {rest}".strip()

    # Define commands used above
    def do_greet(self, arg):
        """Greet someone. Usage: greet """
        name = arg.strip() or "stranger"
        print(f"Hello, {name}!")

    def do_add(self, arg):
        """Add numbers: add 1 2 3"""
        try:
            nums = (float(x) for x in shlex.split(arg))
        except Exception:
            print("Usage: add  ( ...)")
            return
        print(f"Sum = {sum(nums)}")

    def do_exit(self, arg):
        """Exit the shell."""
        print("Goodbye!")
        return True
(myshell) ?
Documented commands (type help ):
========================================
add  exit  greet  help

(myshell) sum 2 3 4
Sum = 9.0

(myshell) add 2 3 4
Sum = 9.0

(myshell) q
Goodbye!

!! Step 6: Keep it all together

import cmd
import shlex

class MyShell(cmd.Cmd):
    intro = "Welcome to MyShell! Type help or ? to list commands."
    prompt = "(myshell) "

    # Simple aliases
    aliases = {"q": "exit", "quit": "exit", "hello": "greet", "sum": "add"}

    # ----- Input processing -----
    def precmd(self, line):
        parts = line.strip().split(maxsplit=1)
        if not parts:
            return line
        cmd_name = parts(0)
        rest = parts(1) if len(parts) > 1 else ""
        if cmd_name in self.aliases:
            cmd_name = self.aliases(cmd_name)
        return f"{cmd_name} {rest}".strip()

    def emptyline(self):
        # Do nothing on empty line
        pass

    def default(self, line):
        print(f"Unknown command: {line!r}. Type 'help' to list commands.")

    # ----- Commands -----
    def do_greet(self, arg):
        """Greet someone. Usage: greet """
        name = arg.strip() or "stranger"
        print(f"Hello, {name}!")

    def help_greet(self):
        print("greet ")
        print("  Prints a friendly greeting.")
        print("  Example: greet Alice")

    def do_add(self, arg):
        """Add numbers: add 1 2 3"""
        try:
            nums = (float(x) for x in shlex.split(arg))
        except Exception:
            print("Usage: add  ( ...)")
            return
        print(f"Sum = {sum(nums)}")

    def do_echo(self, arg):
        """Echo back what you type: echo """
        print(arg)

    def do_exit(self, arg):
        """Exit the shell."""
        print("Goodbye!")
        return True

    # ----- Help tweaks -----
    def do_help(self, arg):
        if arg:
            return super().do_help(arg)
        super().do_help(arg)
        print()
        print("Basics:")
        print("  - Use 'help' or '?' to list commands.")
        print("  - Use 'help ' for details.")
        print('  - Quotes are supported in arguments (e.g., add "3.5" 2).')

if __name__ == "__main__":
    MyShell().cmdloop()
Welcome to MyShell! Type help or ? to list commands.
(myshell) hello
Hello, stranger!
(myshell) WRONG COMMAND
Unknown command: 'WRONG COMMAND'. Type 'help' to list commands.
(myshell) echo KDnuggets is a great site
KDnuggets is a great site
(myshell) exit
Goodbye!

. Wrap

How to make an interactive shell you’ve just learned cmd Module without any external dependence. Isn’t that amazing?

Before we finish, it is worth indicating Some common losses To see: First, forget to come back True The shell loop in your exit command will stop the end. Second, relying on the SIMPLE SIMPLE SIMPLE SIMPLE WITH SPECS DIFFERENCE WHILE IN THE CONTACT IN CONTACTED IN THE CONTACTED LOOKING, so using shlex Recommended. Finally, not handling emptyline() The method can properly cause unexpected behavior, such as repeating the last command when the user enters the empty line.

I would love to listen to your thoughts about this article in the comment section, as well as find your thoughts more.

Kanwal seals A machine is a learning engineer and is a technical author that has a deep passion for data science and has AI intersection with medicine. He authored EBook with “Maximum Production Capacity with Chat GPT”. As a Google Generation Scholar 2022 for the APAC, the Champions Diversity and the Educational Virtue. He is also recognized as a tech scholar, Mitacs Global Research Scholar, and Harvard Vacod Scholar as a Taradata diversity. Kanwal is a passionate lawyer for change, who has laid the foundation of a Fame Code to empower women in stem fields.

You may also like

Leave a Comment

At Skillainest, we believe the future belongs to those who embrace AI, upgrade their skills, and stay ahead of the curve.

Get latest news

Subscribe my Newsletter for new blog posts, tips & new photos. Let's stay updated!

@2025 Skillainest.Designed and Developed by Pro