如何用c语言写一个shell

用c语言编写如下程序:
编写一个简单的shell,可以运行不带参数的外部命令,支持标准I/O重定向,可以通过管道连接两个命令。(外部命令的路径可以是固定路径)。

求示例代码。翻遍鸟哥都只找到shell的脚本编程,哪位大牛知道用c语言写一个shell解释器要怎么弄啊?求大神指点啊!!!

鸟哥是不会有这个的,可以这样想(感觉这样很麻烦,只用一对管道应该也可以,流程也能简单,控制好进程顺序就行。这个编得过):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>

#define CMD_LINE 1024
#define PIPE_MAX 16
#define ARG_MAX 10

typedef struct {
char *arg[ARG_MAX];
char *in;
char *out;
} cmd_t;

extern int parse_token(char *buf, cmd_t cmd[]);
extern int parse(char *buf, cmd_t * cmd);
extern int test_parse(cmd_t cmd[], int len);

int main(int argc, char *argv[])
{
char buf[CMD_LINE];
cmd_t cmd[PIPE_MAX + 1];
int fd[PIPE_MAX][2];
int j, i;
int cmd_len, pipe_len;
pid_t pid;

while (1) {
printf("my_shell#");

fgets(buf, CMD_LINE, stdin);
buf[strlen(buf) - 1] = '\0';
cmd_len = parse_token(buf, cmd);

pipe_len = cmd_len - 1;
if (pipe_len > PIPE_MAX)
continue;

for (i = 0; i < pipe_len; ++i)
pipe(fd[i]);

for (i = 0; i < cmd_len; ++i)
if ((pid = fork()) == 0)
break;

if (pid == 0) {
if (pipe_len) {
if (i == 0) {
close(fd[i][0]);
dup2(fd[i][1], 1);
close(fd[i][1]);
for (j = 1; j < pipe_len; ++j)
close(fd[j][0]),
close(fd[j][1]);
} else if (i == pipe_len) {
close(fd[i - 1][1]);
dup2(fd[i - 1][0], 0);
close(fd[i - 1][0]);
for (j = 0; j < pipe_len - 1; ++j)
close(fd[j][0]),
close(fd[j][1]);
} else {
dup2(fd[i - 1][0], 0);
close(fd[i][0]);
dup2(fd[i][1], 1);
close(fd[i][1]);
for (j = 0; j < pipe_len; ++j) {
if ((j != i - 1)
|| (j != i))
close(fd[j][0]),
close(fd[j]
[1]);
}
}
}
if (cmd[i].in) {
int fd = open(cmd[i].in, O_RDONLY);
dup2(fd, STDIN_FILENO);
close(fd);
}
if (cmd[i].out) {
int fd =
open(cmd[i].out,
O_RDWR | O_CREAT | O_TRUNC, 0644);
dup2(fd, STDOUT_FILENO);
close(fd);
}
execvp(cmd[i].arg[0], cmd[i].arg);
fprintf(stderr, "Failed exec\n");
exit(127);
}
/* parent */
for (i = 0; i < pipe_len; ++i)
close(fd[i][0]), close(fd[i][1]);
for (i = 0; i < cmd_len; ++i)
wait(NULL);
}

return 0;
}

int parse_token(char *buf, cmd_t cmd[])
{
int n = 0;
#if 1
char *save_p;
char *p = strtok_r(buf, "|", &save_p);
while (p != NULL) {
parse(p, &cmd[n++]);
p = strtok_r(NULL, "|", &save_p);
}

#else
cmd[n].arg[0] = "ls";
cmd[n].arg[1] = "-l";
cmd[n].arg[2] = NULL;

#endif
return n;
}

int test_parse(cmd_t cmd[], int len)
{
int i;
for (i = 0; i < len; ++i) {
printf("cmd[%d]:", i);
int j = 0;
while (cmd[i].arg[j])
printf(" %s", cmd[i].arg[j++]);
if (cmd[i].in)
printf("\tin:%s", cmd[i].in);
if (cmd[i].out)
printf("\tout:%s", cmd[i].out);
printf("\n");
}
return 0;
}

int parse(char *buf, cmd_t * cmd)
{
int i = 0;
cmd->in = NULL;
cmd->out = NULL;
char *p = strtok(buf, " ");
while (p) {
if (*p == '<') {
if (*(p + 1))
cmd->in = p + 1;
else
cmd->in = strtok(NULL, " ");
} else if (*p == '>') {
if (*(p + 1))
cmd->out = p + 1;
else
cmd->out = strtok(NULL, " ");
} else
cmd->arg[i++] = p;
p = strtok(NULL, " ");
}
cmd->arg[i] = NULL;
return 0;
}
温馨提示:内容为网友见解,仅供参考
第1个回答  推荐于2017-09-04
#include <stdio.h>
#include <unistd.h>

int main() {

// exec 系列函数出错时会返回 -1,平常返回 0,所以可以
// 据此来打印错误信息
// 第一个 ls 是命令的名称,execlp 函数会自动在 $PATH
// 中寻找这个命令。
// 后面一个 ls 是要在 shell 中输入的第一个参数
//(也就是命令名称本身)
// 使用 NULL 作为参数结尾标记是 exec 系列函数的要求。
if (execlp("ls", "ls", "-l", NULL) == -1)
perror("Error Executing Command.\n");
return 0;
}
第2个回答  2012-05-22
bash源码放哪干嘛的?

如何用c语言写一个shell
\/\/shell指令参数个数int execute(char* arglist[])\/\/执行外部命令{ int error; error=execvp(arglist[0],arglist); if (error==-1) printf("failed\\n"); exit(1);}char* make(char *buf)\/\/将字符串传入参数表内{ char *cp; cp=malloc(strlen(buf)+1); if (...

怎么用C语言写一个DOSshell
void main(void){ while (1) { cmd = get_cmd_from_input();switch (cmd) { case DIR:do_dir();break;case COPY:do_copy();break;} } } }

用C语言实现shell中的 Pushd +n命令
setWindowDirectory(workDirectory);\/\/ 设置历史纪录,写回文件 setDirectoryHistory(directorys);return 0;

如何编写一个shell脚本
echo "your login shell is not bash but $SHELL" fi 变量$SHELL包含了登录shell的名称,我们和\/bin\/bash进行了比较。 快捷操作符 熟悉C语言的朋友可能会很喜欢下面的表达式: [ -f "\/etc\/shadow" ] && echo "This computer uses shadow passwors" 这里&& 就是一个快捷操作符,如果左边的表达式为真则执行右...

在Linux下用C语言编程
4。守护进程的创建 如果你在DOS时代编写过程序,那么你也许知道在DOS下为了编写一个常驻内存的程序我们要编写多少代码了.相反如果在Linux下编写一个"常驻内存"的程序却是很容易的.我们只要几行代码就可以做到. 实际上由于Linux是多任务操作系统,我们就是不编写代码也可以把一个程序放到后台去执行的.我们...

如何在C语言中执行shell命令
if (execlp("ls", "ls", "-l", NULL) == -1) perror("Error Executing Command.\\n"); return 0; }在 shell 中运行这个 C 程序会输出 和你直接在 shell 中写 ls -l 的效果是一样的。然而,如果你使用不带 p 的 execl, 那么这样写就会报错。include <stdio.h>#include...

编写Shell程序,实现功能:计算N!,使用函数的方法实现.
GETFROM=$1exponentiation $GETFROM脚本保存为test.sh chmod u+x test.sh.\/test.sh N (N为你需要计算幂的数字).\/test.sh 103628800 cao_doctor | 发布于2013-01-12 举报| 评论 0 0 为您推荐: 小程序 中断服务程序怎么写 解释程序的功能是 c语言经典程序100例 程序是由什么在编写的 用程序...

shell编程入门(shell编程入门简单吗)
Shell是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。 Shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。 KenThompson的sh是第一种UnixShell,WindowsExplorer是一个典型的图形界面Shell。 Shell与其他Linux命令一样,都是实...

linux下怎样用c语言调用shell命令
方法一、system()的使用。我直接上代码吧 int system(const char *command);我在\/home\/book\/shell新建一个test.sh文件例如以下:#!bin\/bash echo $HOME echo "the is test!" test.c文件例如以下:#include<stdlib.h> int main(){ system("bash \/home\/book\/shell\/test.sh"); \/* chmod +...

c语言怎么编写hill密码?
a是一个列为1的矩阵\\x0d\\x0avoid MultiplyMatrix(int a[], int b[][10], int *text)\\x0d\\x0a{\\x0d\\x0a int i, j, t; for (i = 0; i = size)\\x0d\\x0a sum %= size;\\x0d\\x0a temp1[diff] *= m[row][column];\\x0d\\x0a temp2[sum] *= m[row...

相似回答