简体   繁体   English

自定义linux shell中的管道

[英]Piping in custom linux shell

Trying to implement my own linux shell with a few basic functions and of course an issue comes when it's time to implement the pipes. 试图用一些基本功能实现我自己的linux shell,当然,当需要实现管道时会出现问题。 To be more specific the piping works for the most part, though it seems to drop the last argument. 更具体地说,管道似乎在很大程度上发挥了作用,尽管它似乎放弃了最后一个论点。 For example if I were to run the command 例如,如果我要运行命令

ps ax | grep ps

The ps after the grep command is dropped in my shell. grep命令之后的ps放在我的shell中。 So instead of outputting this as shown using your typical Linux shell 因此,与其使用典型的Linux Shell输出,如图所示,

339 ?        S      0:00 upstart-udev-bridge --daemon
497 ?        Ss     0:00 /usr/sbin/cupsd -F
503 ?        S<     0:00 [kpsmoused]
720 ?        S      0:00 upstart-socket-bridge --daemon
5541 pts/0    R+     0:00 ps ax
5542 pts/0    S+     0:00 grep --colour=auto ps

You get this 你得到这个

339 ?        S      0:00 upstart-udev-bridge --daemon
497 ?        Ss     0:00 /usr/sbin/cupsd -F
503 ?        S<     0:00 [kpsmoused]
720 ?        S      0:00 upstart-socket-bridge --daemon
5557 pts/0    R+     0:00 ps ax

In this case you're not searching for the matching pattern ps. 在这种情况下,您不是要搜索匹配的模式ps。

The function for piping runs as follows 配管功能如下

void mypipes(char* args[], int nargs)
{
  pid_t pid;
  int fd[2];

  char* cmdargs[nargs - 2];
  char* cmdargs2[nargs - 2];


  int i;
  int t = 0;
  int count = 0;

  for(i = 0; i < nargs; i++)
  {
if(!strcmp(args[i], "|"))
{
    //dont put into array
    t = 1;
}
else if(t == 0)
{
    cmdargs[i] = args[i];
    count++;
}
else if(t == 1)
{
    cmdargs2[i - 3] = args[i];
}
  }


  if(count == 2)
  {
  pipe(fd);
  pid = fork();

  if(pid == -1)
  { 
    perror("unable to fork");
    exit(1);
  }
  if(pid > 0)
  {
    wait(&pid);
    close(fd[1]);
    close(0);
    dup2(fd[0],0);
    execlp(cmdargs2[0], cmdargs2[0], cmdargs2[1], NULL);
  }
  if(pid == 0)
  {
    close(fd[0]);
    close(1);
    dup2(fd[1],1);
    execlp(cmdargs[0], cmdargs[0], cmdargs[1], NULL);
  }
  }

  if(count == 1)
  {
  pipe(fd);
  pid = fork();

  if(pid == -1)
  { 
    perror("unable to fork");
    exit(1);
  }
  if(pid > 0)
  {
    wait(&pid);
    close(fd[1]);
    close(0);
    dup2(fd[0],0);
    execlp(cmdargs2[0], cmdargs2[1], NULL);
  }
  if(pid == 0)
  {
    close(fd[0]);
    close(1);
    dup2(fd[1],1);
    execlp(cmdargs[0], cmdargs[1], NULL);
  }

  }

}

I've checked to see if all the variables after the pipe are still within the second set of arguments and they are the issue isn't the main but somewhere where I'm executing the actual piping where it doesn't read to the end. 我检查了管道之后的所有变量是否仍在第二组参数内,它们的问题不是主要问题,而是我正在执行实际管道的地方,但并未读到结尾。

Thank you in advance for any tips on what could be wrong here. 在此先感谢您提供任何可能出现问题的提示。

First, unless I'm missing something, your two sample ouputs both look like they're working: they both only list lines with 'ps' in them. 首先,除非我丢失了某些内容,否则您的两个样本输出看起来都好像在工作:它们都只列出其中带有“ ps”的行。 (If it really was running ps ax | grep then grep would complain about usage). (如果它确实在运行ps ax | grepgrep会抱怨用法)。 The only difference I can see in the outputs is that the second doesn't list the grep process itself, but this can easily happen if the ps has finished grabbing the process-list before the grep is started. 我在输出中看到的唯一区别是,第二个未列出grep进程本身,但是如果psgrep启动之前已完成抓取进程列表,则很容易发生这种情况。

Second, your use of wait(&pid) is odd -- as it's in the child process, it will wait for any of the child-process's children to exit. 其次,您对wait(&pid)很奇怪-因为它在进程中,所以它将等待任何子进程的子进程退出。 As there are none, it will return ECHILD (and if there were, it would overwrite pid with the grandchild's exit status). 由于不存在,它将返回ECHILD (如果存在,则将用孙子的退出状态覆盖pid )。

Third, your use of t , cmdargs and cmdargs2 together with count to decide which execlp call to make only works if it's of the form cmd1 arg1 | cmd2 arg2 第三,使用tcmdargscmdargs2以及count来决定仅当cmd1 arg1 | cmd2 arg2形式的execlp调用才有效cmd1 arg1 | cmd2 arg2 cmd1 arg1 | cmd2 arg2 -- almost any other combinaation won't work. cmd1 arg1 | cmd2 arg2 arg2-几乎所有其他组合均不起作用。 A couple of points: 要点:

  • instead of [i -3] to save the arguments after the pipe, you need to remember at which position you saw the pipe (eg instead of t=1 , use t=i+1 when you find the pipe and cmdargs2[it] when saving the arguments after it). 而不是[i -3]来将参数保存在管道之后,您需要记住在哪个位置看到管道(例如,当找到管道和cmdargs2[it]时,使用t=i+1代替t=1 ,保存之后的参数时)。
  • you'll want to look at the execvp() version of the function call, so that you can pass in arrays of arguments (remembering to add a NULL element after all the ones from the command-line). 您需要查看函数调用的execvp()版本,以便您可以传入参数数组(记住要在命令行中的所有元素之后添加一个NULL元素)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM