- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在用 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展开.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);
在流程中,我们分配一个新行:
char expanded_line[EXPANDEDLEN];
然后我们在expand.c中调用expand:
expand(line, expanded_line, EXPANDEDLEN);
在expand中,我们将字符从line逐字复制到expanded_line,直到找到$(,然后调用:
static int expCmdOutput(char *orig, char *new, int *oldl_ind, int *newl_ind)
orig 是行,new 是扩展行。 oldl_ind 和 newl_ind 分别是该行和扩展行中的当前位置。然后我们通过管道,递归调用流程,向其传递嵌套命令(例如,如果我们有“echo a $(echo b)”,我们将传递流程“echo b”)。
这就是我感到困惑的地方,每次调用expand时,它是否会分配一个新的内存块EXPANDEDLEN long?如果是这样,这很糟糕,因为我很快就会用完堆栈空间(在大量嵌套的命令行输入的情况下)。在扩展中,我在扩展字符串的末尾插入了一个空字符,那么为什么它会打印过去呢?
如果你们需要更多代码或解释,请询问。其次,我将代码放在pastebin中,因为代码量很大,而且根据我的经验,当我用代码填满几页时,人们不喜欢它。
最佳答案
您的问题在于expCmdOutput
。正如您已经注意到的,使用 read
读取子进程的输出时,您不会获得 NUL 终止的字符串。您想要做的是通过添加类似的内容来手动终止字符串
buf[bytes_read] = '\0';
在第 29 行 (expand.c) 中调用 read
之后。因为 NUL 需要空间,所以当然只能读取 BUF_SIZE - 1
字节。
不过,您可能应该重新考虑之后执行的整个循环:
/* READ OUTPUT OF COMMAND FROM READ END OF PIPE, THEN CLOSE READ END */
bytes_read = read(fd[0],buf,BUF_SIZE);
while(bytes_read > 0)
{
bytes_read = read(fd[0], buf, BUF_SIZE);
if (bytes_read == -1) perror("read");
}
close(fd[0]);
如果命令的输出长于 BUF_SIZE,您只需再次读取 buf
,覆盖刚刚读取的输出。这里您真正想要的是分配内存并使用 strcat
附加到末尾(或者通过保存指向字符串末尾的指针以提高效率)。
关于C Minishell 命令扩展打印乱码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13447205/
所以我正在用 C(用于 unix)构建一个 minishell。我只是想出了如何让管道工作,但是我遇到了僵尸问题。假设我有: echo a | echo b | echo c 这不输出任何东西,当它应
我正在用 C 语言编写一个 unix minishell,并且正在添加命令扩展。我的意思是我可以将命令嵌套在其他命令中,例如: $> echo hello $(echo world! ... $(ec
我正在编写一个迷你 shell 程序。它给了我“args = my_str2vect(line);”行中的段错误。不过,“my_str2vect”函数以及 my_strncpy 函数和 my_strl
我实际上正在尝试用 C 实现一个基本的 minishell。为此,我制作了一个函数来解析用户在控制台中输入的内容。我解析了它,然后我想使用管道将命令发送到控制台。我不明白为什么我的管道不工作。我检查了
嗨,我最近开始学习unix系统编程。 我正在尝试用 c 创建一个 minishell,但是当我运行我的代码时, 我总是得到: EXC_BAD_ACCESS (code=EXC_I386_GPFLT 不
基本上我想做的是: 如果我写 Hello I am here char command[20] 应该是 'Hello'(那部分有效)并且 char *parameters 应该有指向 ' 你好' '我
我用 C 做了一个简单的 minishell,它可以工作,除了 cd 命令。当我尝试运行它时,除了它创建了一个永远不会真正结束的子进程之外,什么也没有发生。例如,在我的 minishell 中运行 c
我正在尝试编写一个内置功能非常有限的 minishell。但是,现在每当我处理 SIGINT 时,我都必须再次按回车键才能输入更多命令。 void loop() { struct sigact
我正在用 C 语言制作一个 minishell,我正在考虑环境变量。我从用户那里获取原始输入行,并将其传递给一个函数: int expand(char *orig, char *new, int ne
我在我的操作系统签名中用 c 语言制作了一个 UNIX minishell。我只需要改进 shell 本身,我们有一个用于实现 yacc 的预制解析器和一个用于在其他文件中实现 lex 的扫描器。要修
我正在尝试用这段代码编写一个 minishell: #include #include #include #define LINE_LEN 50 #define MAX_PARTS 50 i
这个问题在这里已经有了答案: Is it possible to distinguish the error returned by fgets (2 个答案) 关闭 2 年前。 我写了这个 min
我是一名优秀的程序员,十分优秀!