shell 解析字符串时,代码是否添加了字符串内容和字符串的最后一部分?[已关闭]

5t7ly7z5  于 2022-12-13  发布在  Shell
关注(0)|答案(2)|浏览(100)

**已关闭。**此问题需要debugging details。当前不接受答案。

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
两个月前关门了。
此帖子已在8天前编辑并提交审核,无法重新打开帖子:
原始关闭原因未解决
Improve this question
我正在用Python制作自己的shell,并试图使它尽可能的用户友好和可定制。但是我在解析命令行字符串时遇到了一个问题。
我有一个要传递给命令的参数列表。
当我尝试:

echo "Hello World!"

我的参数如下所示:

['Hello World!', 'World!"']

而不是这个(期望的输出):

['Hello World!']

这个问题不是错误,只是代码中的错误。
下面是我的命令解析器(如果你向它传递一些东西,它应该会自己工作):

import os
import imp

from rich.console import Console

def handle_command(console: Console, command: str):
    split_string = command.split(" ")
    command_name = split_string[0]
    command_name = command_name.lower()

    if command_name == "":
        return True

    args = []

    for i in range(1, len(split_string)):
        if split_string[i].startswith('"'):
            res = ""

            pos = i

            while pos <= len(split_string):
                try:
                    res += f"{split_string[pos]} "
                except IndexError:
                    console.print(f"[bold bright_red]ERR: Unterminated string in command arguments[/bold bright_red]")
                    return False
                if split_string[pos].endswith('"'):
                    break
                pos += 1

            if pos == len(split_string):
                if not split_string[pos].endswith('"'):
                    console.print(f"[bold bright_red]ERR: Unterminated string in command arguments[/bold bright_red]")
                    return False

            res = res.replace('"', "")

            args.append(res)
            continue

        args.append(split_string[i])

    commands_dir = os.path.join(os.getcwd(), "shells/Fresh/commands")
    
    if os.path.exists(commands_dir) and os.path.isdir(commands_dir):
        for f in os.listdir(commands_dir):
            if os.path.isfile(os.path.join(commands_dir, f)):
                #try:
                    cmd = imp.load_source(command_name, os.path.join(commands_dir, f))

                    if cmd.name == command_name:
                        if cmd.min_args <= len(args):
                            if cmd.max_args >= len(args):
                                cmd.run(console, args)

                                return True
                            else:
                                console.print(f"[bold bright_red]ERR: {command_name} takes a maximum of {cmd.max_args} arguments[/bold bright_red]")
                                return False
                        else:
                            console.print(f"[bold bright_red]ERR: {command_name} requires atleast {cmd.min_args} argument[/bold bright_red]")
                            return False
                #except Exception as e:
                    #console.print(f"[bold red]ERR: An error occured while running this command[/bold red]")
                    #return False

        console.print(f"[bold bright_red]ERR: Invalid or unkown command '{command_name}'[/bold bright_red]")
        return False
    else:
        raise FileNotFoundError("Commands directory is corrupted or does not exist")
6uxekuva

6uxekuva1#

在您的示例中,

split_string = ["echo", '"Hello', 'World!"']

因此:

for i in range(1, len(split_string)):

将执行2次(一次用于Hello,一次用于World)
它首先将Hello world!添加到args,而不是continue,这次将添加'World!"',因为它不符合

if split_string[i].startswith('"')

我认为这里的问题主要是令牌的解释方式。通常,当命令包含字符串时,仅仅用空格来拆分字符串是不足以正确解析命令的
我觉得你应该看看什么是词汇分析器

txu3uszq

txu3uszq2#

您使用split_string = command.split(" ")拆分命令,因此将获得三个项['echo', '"Hello', 'World!"']
从索引1 for i in range(1, len(split_string)):开始迭代。
您的代码会遍历并正确解析'Hello World!',但问题是您在while循环后添加了args.append(split_string[i])这一行。
因此,它会将'World!"'附加到结果,因为if split_string[i].startswith('"'):将返回False

相关问题