将用户的输入管道输入shell以运行命令

时间:2018-01-30 06:10:56

标签: c shell

我有一个用C语言编写的基本shell,但我仍然停留在用户输入和管道进入shell。我希望将字符串变量current_command传送到工作shell中。

#include <time.h>
#include <sys/utsname.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/utsname.h>
#include <sys/types.h>

//for Ptrace:
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <sys/reg.h>

void type_prompt();

#define TRUE 1
#define CHAR_MAX 100 //set max string length to 9
#define CMND_ARGS_MAX 9 // maximum 9 arguments for command
int main(void)
{
   //command is a string with max length 100
   //params is a 2d array; 9 possible arguments, each being a str with max len 100
   char command[CHAR_MAX] , params[CMND_ARGS_MAX][CHAR_MAX];

   printf("Hello, World\n");
    char buf[128]; //max lenght of date string = 128 chars
    struct tm *today;
    time_t now;

    time(&now);
    today=localtime(&now);

    strftime(buf,128,"%d/%m/%Y",today);
    printf("Today is %s\n",buf);

    int pid, status;


    char current_command[100];


    while(TRUE) { 
        printf("Enter 'exit' to exit into the shell\n$");
        scanf("%s", current_command); //PIPE THIS INTO SHELL
        printf("%s\n", current_command);

        if(strcmp("exit", current_command) == 0) {
          printf("\n\n~~~~~Welcome to the shell~~~~~\n\n$");

          break;
        }

        pid_t child;
        long orig_eax;
        child = fork();
        if(child == 0) { 
            printf("Ptrace executing...\n");
            ptrace(PTRACE_TRACEME, 0, NULL, NULL);
            execl("/bin/ls", "ls", NULL);
        }
        else {
            wait(NULL);
            orig_eax = ptrace(PTRACE_PEEKUSER,
                              child, 4 * ORIG_RAX,
                              NULL);
            printf("The child made a "
                   "system call %ld\n", orig_eax);

            ptrace(PTRACE_CONT, child, NULL, NULL); //put into program()
        }
    return 0;
}

3 个答案:

答案 0 :(得分:0)

shell 的工作是来接受命令并运行它。如果您正在实现shell,则不能只接受命令并将其发送到/bin/sh,因为 也是一个shell。完整的解释超出了范围,但基本思路是:

  1. fork()以便有父子进程
  2. 在子进程中,使用exec()将当前进程替换为用户提供的程序
  3. 在父级中,使用wait()确定子进程何时退出。
  4. 可以找到更详细的解释和示例代码here(免责声明 - 我写的)。

答案 1 :(得分:0)

我不太清楚你的问题 我知道你想制作一个shell,你在重定向方面遇到了一些问题。

我想你已经知道如何使用fork(),wait()和execve()
我建议你也读一下dup2的人。

dup2()将在参数中使用2 fd 不要犹豫,只是做一个糟糕的测试,试图执行&#34; ls -l | cat -e&#34;,例如。

你让我意识到我完全忘记了我是如何制作我的贝壳的,就在5-6个月前! :&#39)

祝你好运!

答案 2 :(得分:0)

要向程序发送一些输入,您需要管道其stdin。

基本上你想要使用pipe()创建一个管道,然后使用fork(),然后使用dup2()创建一个管道。假设您管道int fd[2],因此您需要调用dup2(fd[0], STDIN_FILENO)(子进程),并从主进程:写入管道的写入端:write(fd[1], current_command, strlen(current_command);然后{{ 1}}。

我不是专家,但这是主要想法。