我正在用 C 编写一个 unix minishell,并且正在添加命令扩展。我的意思是我可以将命令嵌套在其他命令中,例如:
$> echo hello $(echo world! ... $(echo and stuff))
hello world! ... and stuff
我想我大部分时间都在工作,但是它没有正确标记扩展字符串的结尾,例如,如果我这样做:
$> echo a $(echo b $(echo c))
a b c
$> echo d $(echo e)
d e c
看到它打印 c,即使我没有要求它。这是我的代码:
msh.c - http://pastebin.com/sd6DZYwB expand.c - http://pastebin.com/uLqvFGPw
我有更多代码,但有很多,这些是我目前遇到问题的部分。我会试着告诉你我这样做的基本方法。
Main 在 msh.c 中,这里它从命令行或 shellfile 中获取一行输入,然后调用 processline (char *line, int outFD, int waitFlag),其中 line 是我们刚刚得到的行,outFD 是输出文件的文件描述符,waitFlag 告诉我们如果我们 fork 是否应该等待。当我们从 main 调用它时,我们这样做:
processline (buffer, 1, 1);
在 processline 中,我们分配一个新行:
char expanded_line[EXPANDEDLEN];
然后我们在 expand.c 中调用 expand:
expand(line, expanded_line, EXPANDEDLEN);
在 expand 中,我们将字符从 line 复制到 expand_line,直到找到 $(,然后调用:
static int expCmdOutput(char *orig, char *new, int *oldl_ind, int *newl_ind)
orig 是线,new 是扩展线。oldl_ind 和 newl_ind 分别是行和扩展行中的当前位置。然后我们通过管道递归调用 processline,将嵌套命令传递给它(例如,如果我们有“echo a $(echo b)”,我们将传递 processline“echo b”)。
这就是我感到困惑的地方,每次调用 expand 时,它是否分配了一块新的内存 EXPANDEDLEN 长?如果是这样,这很糟糕,因为我会很快用完堆栈空间(在大量嵌套的命令行输入的情况下)。在扩展中,我在扩展字符串的末尾插入了一个空字符,那么为什么它会打印过去呢?
如果你们需要更多代码或解释,请询问。其次,我将代码放在 pastebin 中,因为它有很多,而且根据我的经验,当我用代码填满几页时人们不喜欢它。