c - 通过 C 代码在简单的 shell 上保存历史命令
问题描述
我正在用C语言在linux中编写一个简单的shell。我将命令保存在历史记录中,当输入!!时,程序将执行历史记录中保存的最后一个命令。但它不起作用,问题是:
当我输入命令时:ls,argv是ls,历史是ls,但是我输入!!,argv和history都是!!。有人帮我修复这个错误。非常感谢你 !!
void main(void)
{
char line[1024];
char *argv[64];
char *history[64];
while (1) {
printf("Shell -> ");
gets(line);
printf("\n");
parse(line, argv);
if (strcmp(argv[0], "exit") == 0)
exit(0);
checkDoubleExclmt(argv, history);
execute(argv);
}
}
void copyArr(char** des, char** source)
{
int i = 0;
for(i; i < sizeof(source)/4; i++)
{
des[i] = source[i];
}
}
void checkDoubleExclmt(char** argv, char** history)
{
if(strcmp(argv[0], "!!") == 0)
{
if(history[0] == NULL)
{
printf("\nNo Command in history\n");
}
else
{
copyArr(argv, history);
}
}
else
{
copyArr(history, argv);
}
}
void execute(char **argv)
{
pid_t pid;
int status;
if ((pid = fork()) < 0) {
printf("*** ERROR: forking child process failed\n");
exit(1);
}
else if (pid == 0) {
if (execvp(*argv, argv) < 0) {
printf("*** ERROR: exec failed\n");
exit(1);
}
}
else {
while (wait(&status) != pid)
;
}
}
void parse(char *line, char **argv)
{
while (*line != '\0') {
while (*line == ' ' || *line == '\t' || *line == '\n')
*line++ = '\0';
*argv++ = line;
while (*line != '\0' && *line != ' ' &&
*line != '\t' && *line != '\n')
line++;
}
*argv = '\0';
}
解决方案
我看到的主要问题是您正在执行指针复制而不是其内容。
des[i] = source[i]; // pointer copy
应该
des[i] = strdup(source[i]); //creates memory and copies the contents. You need to free the memory before overwriting.
如果您要使用strdup
您的parse()
功能,则需要更改以适应内容副本。
和
for(i; i < sizeof(source)/4; i++)
sizeof(source
是指针的大小而不是数组的大小,您需要将大小显式传递给函数。
推荐阅读
- vagrant - 将 /src 映射到 /home/vagrant
- ios - 识别新的或不流行的特定 iOS 设备,例如 iPad 2018
- angular - 如何使用 Obserservable 创建 httpGate
- php - php dot 和 mysql dot 不匹配
- python - 在python3的模块中导入兄弟文件
- python - 生成无重复的四位数列表
- html - 固定页脚调整大小
- unit-testing - 单元测试 - 实体(模型类)是什么双重(演员)?
- c# - C#: O(n²) solution to finding n/k elements of an array of of size n and a number k
- macos - SSHFS 挂载远程 ssh 服务器导致分段错误:Mac OS 上的 11