【问题标题】:Parsing quoted and double quoted lines in Linux libreadline在 Linux libreadline 中解析带引号和双引号的行
【发布时间】:2020-09-02 02:56:28
【问题描述】:

我正在用 C 语言中的libreadline Linux 库编写自己的 shell。在readline() 中,它从 shell 中获取行并用空格字符解析并将其存储到指针变量中。现在,我想解析这些行以获取包含命令和执行命令的文件名的命令行参数。

我遇到了这个问题,如果文件名有空格名称并且解析如下所示

myshell$ ls 'file name 1' 'file name 2' file\ name\ 3

上面的cli解析如下

ls
'file
name
1'
'file
name
2'
file\
name\
3

所以,请帮我解决这个问题,从 readline 中获取间隔文件名。

这里是我调用 readline 的代码 sn-p。

    while (!done)
    {
        temp = readline (prompt);

        /* Test for EOF. */
        if (!temp)
            exit (1);

        /* If there is anything on the line, print it and remember it. */
        if (*temp)
        {
            add_history (temp);
        }

        <Other stuffs to execute the command>
    }

用标记器更新了帖子。

    ptr = strtok(temp, " ");
    while(ptr != NULL) {
        printf("%s\n", ptr);
        ptr = strtok(NULL, " ");
    }

【问题讨论】:

  • 如果这是 C 不要标记为 C++。
  • 你的解析码在哪里?没有它,这只是一篇关于你很酷的副项目的日记。
  • 感谢您的 cmets。添加代码sn-p。
  • 认为我们也需要add_history。顺便说一句:你有没有测试过你从中得到了什么:printf("%s\n", temp);
  • OT:不知道&lt;Other stuffs to execute the command&gt;是否可以处理空行...

标签: c linux readline


【解决方案1】:

使用 strtok() 的幼稚应用,即使是这种复杂程度的标记化也很困难。即使你可以让它工作,代码也将是不可读和不可维护的。有用于根据规范生成标记器的工具(如 flex),或者您可以使用有限状态机 (FSM) 自己编写逻辑。使用 FSM,您将检查每个字符,并根据标记器的当前状态采取行动。某些状态/字符组合会导致状态变化。

例如,如果您处于“双引号”状态,则不会将空格视为标记的结尾。但是,双引号状态中的双引号字符将表示从该状态转换到其他状态。状态和它们之间的字符类形成一种矩阵,其中的条目控制遇到状态和字符类的每种组合时要采取的动作。

FWIW 我有一个简单的实现,可以按照你想要的方式解析 ASCII 文本;请参阅此代码中的 tokenize() 函数:

https://github.com/kevinboone/xine-server/blob/master/client/src/string.c

如果您正在创建外壳,请注意“真实”外壳中的标记化逻辑非常复杂,并且通常使用工具来实现。此外,大多数现代现实应用程序都需要宽字符支持,这又增加了一层复杂性。

【讨论】:

    猜你喜欢
    • 2017-11-18
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 2014-02-26
    相关资源
    最近更新 更多