我有一个问题与执行()。我正试图编写一个简单的shell程序,它将使用getline()从用户读取输入,然后使用execve()执行。当我输入一个命令(输入),我得到这个错误消息:
vagrant@ubuntu-focal:~/shell_exercises$ ./shell
#cisfun$ /bin/ls
line: /bin/ls
argv[0]: /bin/ls
Error:: No such file or directory
#cisfun$
我已经尝试运行路径=/bin/ls的程序,但它不工作。我做错了什么?提前感谢。下面是代码:
int main(void)
{
char *line, *argv[] = { NULL, NULL }, *env[] = {NULL};
size_t len = 0;
ssize_t nread;
do {
printf("#cisfun$ ");
nread = getline(&line, &len, stdin);
if (nread == -1)
{
perror("can't read commandn");
exit(95);
}
printf("line: %s", line);
if (line == NULL)
{
printf("hello dawg");
continue;
}
else
{
argv[0] = line;
printf("argv[0]: %s", argv[0]);
if (execve(line, argv, env) == -1)
{
perror("Error:");
}
}
} while (1);
free(line);
return (0);
}
代码如下:
int main(void)
{
读取sycall(2)和getline(3)。
部分标题缺失。
至少printf(3)中提到的#include <stdio.h>
和execve(2)中提到的#include <unistd.h>
;您可能还需要阅读exec(3)和environ(7)..)
然后编译你的bayer.c
源代码与所有的警告和调试信息:
gcc -Wall -Wextra -g bayer.c -o bayershell
改进C代码以获得无警告
然后阅读GCC和GDB(调试器)的文档,然后尝试gdb --help
,然后
gdb bayershell
注意proc(5)和每个shell应该使用fork(2)(大师可以尝试clone(2)…)因为它需要启动进程(稍后为它们waitpid(2))
你可能需要阅读stdio(3)然后fflush(3)和关于Linux的教程幻灯片(这些是我用法语写的)。
英文阅读Advanced Linux Programming或一本更好的书。
学习现有开源shell的源代码
类似于sash或GNU bash
您可能想要使用GNU make来编译您的shell项目。你需要阅读它的文档。
您可能希望在源代码中使用GNU缩进。我建议使用版本控制系统比如git(可能在github上)。如果使用正确,它有助于防止错误(如删除源代码文件)。
如果nread
小于len
会发生什么?
也考虑学习和使用valgrind。
注意getline(3)正在读取行结束符。在大多数Linux系统上,没有名为"/bin/lsn"
的文件(其名称以换行符结尾)。您可能需要strchr(3)来删除结束换行字符n
。您甚至可以考虑使用GNU readline(它可能会重用以前的缓冲区),并考虑后面的一些自动完成…
今天,计算机使用UTF8。到处阅读有关UTF8的内容。我的(法语)键盘有§和°键,你的用户可以从他/她的web浏览器复制/粘贴∃
。