【问题标题】:Weird execlp() command奇怪的 execlp() 命令
【发布时间】:2017-04-19 21:39:41
【问题描述】:

所以我基本上需要在c中制作这个命令

find . -type f -ls | cut -c 2- | sort -n -k 7 >file.txt ; less <file.txt

程序正在运行,但它不执行 &gt;file.txtless &lt;file.txt 中的 &gt;,&lt;

我这样写 execlp()

execlp("sort", "sort","-n", "-k", "7",">file.txt", NULL)

execlp("less","less","<file.txt", NULL)

关于如何编写它们的任何提示?谢谢

-第一个管道带有套接字 AF_UNIX

-第二个管道正常

#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>

char *socket_path = "/tmp/socket";
void child1(); 
void child2(); 
void child3(int *pipe_fd);
void father(pid_t *pid);

int main(int argc, char *argv []) {

  pid_t childpid[3];
  int fd[2];

  if (argc != 1) { 
    puts("ERROR!");
    exit(0);
  }

  //Pipe
  if (pipe(fd) == -1) {
    perror("pipe");
  }

  //Filhos
  childpid[0]=fork(); 

  if(childpid[0]==-1) perror("Erro filho 1");

  else if (childpid[0]==0){
    child1(); // Find
    wait(0);
    exit(1);
  } 
  else{
    childpid[1]=fork(); //filho 2

      if(childpid[1]==-1) perror("Erro filho 2");

      else if (childpid[1]==0){
        child2();// 'cut'
    wait(0);
    exit(1);
      }

      else{
        childpid[2]=fork(); 

    if(childpid[2]==-1) perror("Erro filho 3");

      else if (childpid[2]==0){
        child3(fd); // Sort
        wait(0);
        exit(1);
      }

      else{
        father(childpid); // Less
        wait(0);
        exit(1);
      }
       }
   }
  return(0);
}


void child1() { // FIND

  struct sockaddr_un addr;
  int socket_fd;


  if ( (socket_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    perror("socket filho1");
    exit(-1);
  }


  memset(&addr, 0, sizeof(addr));
  addr.sun_family = AF_UNIX;

  if (*socket_path == '\0') {
    *addr.sun_path = '\0';
    strncpy(addr.sun_path+1, socket_path+1, sizeof(addr.sun_path)-2);
  } 

  else {
    strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
  }


  while (connect(socket_fd, (struct sockaddr *)&addr, (socklen_t)sizeof(addr)) == -1) {
    if (errno != ENOENT && errno != ECONNREFUSED) {
      perror("Erro connect filho 1");
    }
  }


  if( dup2(socket_fd,1) == -1) {  //escreve no output!
    perror("Erro no dup filho 1");
  }

  if( close(socket_fd) == -1) {
   perror("Erro no close filho 1");
  }

  if( execlp("find","find", ".", "-type", "f", "-ls", NULL) == -1) {
    perror("Find");
  }
}

void child2() { // CUT

  wait(0);
  struct sockaddr_un  local, remote;
  socklen_t           socket_length = (socklen_t)sizeof(remote);
  int socket_fd, saida_fd;


  if ((socket_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    perror("Erro no socket\n");
    exit(-1);
  }

  memset(&local, 0, sizeof(local));
  memset(&remote, 0, sizeof(remote));

  local.sun_family = AF_UNIX;
  strcpy(local.sun_path, socket_path);

  if (unlink(socket_path) == -1){     
    if (errno != ENOENT){
      perror("filho2 unlink");
    }
  }

  if (bind(socket_fd, (struct sockaddr *)&local,(socklen_t)(strlen(local.sun_path) + sizeof(local.sun_family))) == -1){
    perror("filho 2  bind");
  }

  if (listen(socket_fd, 1) == -1) {
    perror("Erro no listen");
  }

  if ((socket_fd = accept(socket_fd, (struct sockaddr *)&remote, &socket_length)) == -1){
    perror("filho 2 accept");
  }

  if( dup2(socket_fd,0) == -1) { // recebe do output!
    perror("dup2(1) do  filho 2");
  }

  if( close(socket_fd) == -1) {
    perror("Failed to close(1) child 2");
  }

  //--------------------------------------------------//
  if((saida_fd = open("file.txt", O_WRONLY )) == -1) {
    perror("Open filho 2");
  }

  if( dup2(saida_fd,1) == -1) { 
    perror("Failed to dup2(2) child 2");
  }

  if(close(saida_fd) ==  -1) { 
    perror("Failed to close(2) child 2");
  }

  if(execlp("cut", "cut", "-c", "2-", (char *)NULL) == -1 ){
    perror("Cut");
  }
}


void child3(int *pipe_fd) // SORT
{
  int fd;

  if (close(pipe_fd[1]) == -1){
    perror("erro no close da escrita do filho3");
  }

  if (dup2(pipe_fd[0], STDIN_FILENO) == -1){
    perror("erro no dup do filho 3 ");
  }

  if (close(pipe_fd[0]) == -1){
    perror("erro no close da leitura do filho 3 ");
  }

  if ((fd = open("file.txt", O_RDWR)) == -1) {
    perror("erro no open do pai");
  }

  if (dup2(fd, 1) == -1) {
    perror("erro no dup do filho 3");
  }

  if (close(fd) == -1){
    perror("erro no close 3 do filho 3");
  }

  if (execlp("sort", "sort","-n", "-k", "7",">file.txt", (char*)NULL) == -1) {
    perror("Sort");
  }
}


void father(pid_t *pid) // 'less' 
{
  int i;
  int ID_final;
  int status[4];
  int file_fd;

  if ((file_fd = open("file.txt",O_WRONLY | O_TRUNC | O_CREAT, 0666)) == -1) {
    perror("erro no open pai");
  }

  //espera pelos filhos
  for (i = 0; i < 3; i++){
    while ((ID_final = waitpid(pid[i], &status[i], 0)) != pid[i]){
      if (ID_final == -1){
        perror("erro no waitpid");
      }
    }
  }

  if ((file_fd = open("file.txt", O_RDONLY)) == -1) {
    perror("erro no open do pai");
  }

    if (dup2(file_fd, STDIN_FILENO) == -1){
    perror("erro no dup do pai");
  }

  if (close(file_fd) == -1){
    perror("erro no close do pai");
  }

  if (execlp("less","less","<file.txt", (char*)NULL) == -1){
    perror("erro no 'less'");
  }
}

【问题讨论】:

  • 您必须执行基于文件的 I/O 重定向(&gt;file.txt&lt;file.txt)以及基于管道的 I/O 重定向。 shell 通常会为您处理它,但是当您编写类似 shell 的代码时,您必须忙起来!在运行less 之前,您还需要等到供应sort 的管道完成;否则,less 将找到一个空文件并直接退出。
  • 你知道 ">file.txt" 和 "execlp 是做什么的吗?
  • 重定向是shell的一个特性;它们由外壳执行。 sort 写入stdoutlessstdin 读取,当在命令行中使用&gt;&lt; 时,shell 会将这些流绑定到文件。
  • >file.txt 和

标签: c sockets pipe


【解决方案1】:

重定向由 shell 处理。 在 C 中,您需要成为自己的 shell 并自己进行重定向:

int fd = open("file.txt", O_TRUNC|O_WRONLY);
if(0>fd) /*handle error*/;
dup2(fd, 1 /*STDOUT*/); 
close(fd); /*file.txt is now on fd 1*/
///....
execlp("sort", "sort","-n", "-k", "7", (char*)NULL);

【讨论】:

  • 怎么样?如果我不放它们就不会对它们进行排序
  • 对于&lt;,打开文件O_RDONLY 而不打开O_TRUNC,然后将dup 转到0 而不是1。欲了解更多信息,请阅读友好手册。
  • 当我按照你说的做时,错误消息是 ">file.txt: 没有这样的文件或目录
  • 不@Ackerman,这个答案所说的没有引用名为“>file.txt”或“other 代码,您在其中 not 执行此答案所说的操作。
  • @JohnBollinger 也许问题出在其他地方。我要写所有的代码
猜你喜欢
  • 1970-01-01
  • 2018-02-18
  • 2015-03-28
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 2012-06-21
  • 2022-01-05
  • 2015-12-07
相关资源
最近更新 更多