CMD 모듈로 자신의 파이썬 쉘 생성에 대한 초보자 안내서

CMD 모듈로 자신의 파이썬 쉘 생성에 대한 초보자 안내서

CMD 모듈이있는 파이썬 쉘CMD 모듈이있는 파이썬 쉘
저자의 이미지 | 표의 문자

소개

나는 대부분의 사람들이 어느 시점에서 명령 쉘을 사용했다고 확신합니다. 그렇지 않은 경우 GUI에 비해 지루해 보일 수 있지만 명령 줄 인터페이스 (CLI)는 매우 가벼우 며 훨씬 더 많은 제어 기능을 제공합니다. 몇 가지 일반적인 예는 sqlite, git 및 python repl입니다. 이 튜토리얼에서는 Python의 사용 방법을 배웁니다. cmd 외부 의존성없이 자체 대화식 쉘을 구축하는 모듈. 시작하는 것은 매우 간단하고 직관적입니다. 이와 같은 프로젝트를 수행하면 매일 매일 사용하지만별로 생각하지는 않습니다. 응용 프로그램을 위해 관리자 콘솔을 구축하려는 경우에도 유용합니다.

우리는 최소한의 예에서 시작하여 점차 명령, 도움말, 기본 검증, 별명 및 친절한 출력을 추가하여 작은 청크로 쉘을 만들 것입니다. 귀하의 측면에서 유일한 요구 사항은 Python 기능 및 클래스에 기본적인 친숙 함을 갖는 것입니다. 그래서 시작합시다.

자신의 파이썬 쉘을 구축하기위한 단계별 프로세스

빠른 개요를 가지고합시다 cmd 모듈, 우리는 이미 사용했지만 그것이 무엇인지 설명하지 않았기 때문에. 기본 클래스를 제공합니다 (cmd.Cmd) 빌드 라인 지향 명령 통역사즉, 한 번에 하나의 명령을 처리한다는 것을 의미합니다. 또한 프롬프트, 명령 파견 (텍스트 매핑 메소드) 및 도움말 시스템을 통해 입력을 읽는다. 이름이 지정된 메소드를 정의하여 명령을 구현합니다 do_. 모듈은 나머지 부분을 처리합니다.

// 1 단계 : 최소 쉘 생성

호출 된 파일을 만듭니다 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()

다음을 사용하여 코드를 실행합니다.

이제 몇 가지 명령을 시도해 봅시다. cmdloop() 대화식 루프를 시작하면 다음과 같이 상호 작용할 수 있습니다.

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!

// 2 단계 : 논쟁을 깨끗하게 구문 분석합니다

추가 또는 곱하기와 같은 여러 입력 값이 필요한보다 복잡한 명령의 경우 공간, 따옴표 등을 구문 분석하려면 무언가가 필요합니다. 이를 위해 우리는 사용할 것입니다 shlex.split. 예제 코드를 살펴 보겠습니다.

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()

이제 시도해 봅시다.

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!

// 3 단계 : 도움말 시스템 추가

우리는 이미 위의 하나의 도움 명령을 보았습니다. 그게 기본값입니다 cmd 모듈은 자동으로 생성됩니다. docstrings 방법을 보여줍니다. 다음과 같은 명령 또는 주제에 대해 사용자 정의 도움말을 추가 할 수도 있습니다.

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!

// 4 단계 : 오류 및 알 수없는 명령 처리

우리는 그것을 무시할 수 있습니다 default() 알 수없는 명령을 가로 채는 메소드. 당신은 또한 사용할 수 있습니다 emptyline() 사용자가 입력없이 입력 할 때 발생하는 일을 제어합니다. 입력이 입력되지 않으면 쉘이 아무것도하지 않도록합시다.

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!

// 5 단계 : 명령 별칭 추가

별칭은 짧은 이름입니다. 많은 친구들도 별명, 특히 같은 이름을 가진 별명을 가지고 있습니다. 마찬가지로, 당신은 별명을 구현하여 더 짧고 기억하기 쉬운 명령을 사용할 수 있습니다. precmd() 방법. 이 작업을 수행 할 수있는 방법은 다음과 같습니다.

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!

// 6 단계 : 모든 것을 정리합니다

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!

마무리

방금 cmd 외부 의존성이없는 모듈. 놀랍지 않나요?

우리가 끝나기 전에, 그것은 지적 할 가치가 있습니다 몇 가지 일반적인 함정 조심해야합니다. 첫째, 돌아 오는 것을 잊어 버립니다 True 출구 명령에서 쉘 루프가 끝나는 것을 방지합니다. 둘째, 인수에 대한 간단한 공백 분할에 의존하면 사용자가 인용 된 텍스트를 입력 할 때 문제가 발생할 수 있으므로 shlex 권장됩니다. 마지막으로, 처리하지 않습니다 emptyline() 메소드를 올바르게 올바르게하면 사용자가 빈 줄에 입력 할 때 마지막 명령을 반복하는 것과 같이 예상치 못한 동작으로 이어질 수 있습니다.

이 기사에 대한 귀하의 생각과 더 자세히 살펴보고 싶은 아이디어를 듣고 싶습니다.

Kanwal Mehreen 기계 학습 엔지니어이자 데이터 과학에 대한 열정과 AI의 의학 교차점을 가진 기술 작가입니다. 그녀는 eBook “Chatgpt의 생산성을 극대화하는 것”을 공동 저술했습니다. APAC의 Google Generation Scholar 2022로서 그녀는 다양성과 학업 우수성을 챔피언시킵니다. 그녀는 또한 Tech Scholar, Mitacs Globalink Research Scholar 및 Harvard Wecode Scholar의 Teradata 다양성으로 인정 받고 있습니다. Kanwal은 STEM 분야의 여성에게 힘을 실어주기 위해 펨코드를 설립 한 변화에 대한 열렬한 옹호자입니다.

출처 참조

Post Comment

당신은 놓쳤을 수도 있습니다