0

我想在 C 程序中实现一个简单的“cat file1 > file1”命令。我尝试了以下方法,但它不起作用......

main () {
    pid_t pid;
    FILE *ip, *op;
    char *args[3];
    printf("Name of the executable program\n\t");
    scanf("%s", &name[0]); // I entered cat here
    printf("Name of the input file\n\t");
    scanf("%s", &name[1]); //file1.txt
    printf("Name of the output file\n\t");
    scanf("%s", &name[0]); //file2.txt
    pid = fork();
    if(pid == -1)
        perror("fork() error");
    else if(pid > 0)
        waitpid(-1, NULL, 0);
    else if (pid == 0) {
        op = fopen(name[2], "w");
        close(1);
        dup(op);
        execlp(name[0], name[1], NULL);
        }
    return 0;
    }// end of main()

我以为execlp()将运行cat file1.txt并且它的输出将被重定向到file2.txt,但事实并非如此,我不知道为什么。我该怎么做?

4

3 回答 3

1

第一个参数execlp()是要查找的名称;第二个和后面的参数是argv列表,以 . 开头argv[0]

int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);

open()对于 shell I/O 重定向,打开文件比使用标准 I/O (<stdio.h>和)更容易FILE *;您还应该关闭在 之后打开的文件dup(),尽管它更易于使用dup2()。您需要分配空间来读取字符串;在许多系统上,原始代码会崩溃,因为其中的指针str不指向任何地方。通常,只有在一切正常的情况下,您才应该以状态 0 退出;否则,以非零退出状态退出。

这将导致:

#include <fcntl.h>      /* open() */
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>   /* waitpid() */
#include <unistd.h>     /* execlp(), fork(), dup2() */

int main(void)
{
    pid_t pid;
    pid_t corpse;
    int   status;
    char  name[3][50];
    printf("Name of the executable program\n\t");
    if (scanf("%49s", name[0]) != 1)
        return(EXIT_FAILURE);
    printf("Name of the input file\n\t");
    if (scanf("%49s", name[1]) != 1)
        return(EXIT_FAILURE);
    printf("Name of the output file\n\t");
    if (scanf("%49s", name[2]) != 1)
        return(EXIT_FAILURE);
    pid = fork();
    if (pid == -1)
    {
        perror("fork() error");
        return(EXIT_FAILURE);
    }
    else if (pid > 0)
        corpse = waitpid(-1, &status, 0);
    else
    {
        int fd = open(name[2], O_WRONLY|O_CREAT|O_EXCL, 0644);
        if (fd < 0)
        {
            fprintf(stderr, "Failed to open %s for writing\n", name[2]);
            return(EXIT_FAILURE);
        }
        dup2(fd, 1);
        close(fd);
        execlp(name[0], name[0], name[1], NULL);
        fprintf(stderr, "Failed to exec %s\n", name[0]);
        return(EXIT_FAILURE);
    }
    return(corpse == pid && status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
于 2012-08-13T05:35:15.237 回答
1
scanf("%s", &name[0]); // I entered cat here
printf("Name of the input file\n\t");
scanf("%s", &name[1]); //file1.txt
printf("Name of the output file\n\t");
scanf("%s", &name[0]); //file2.txt

显然不是实际代码的 C&P -name应该是args,最后一个应该是“2”而不是 0。

此外,dup 适用于文件描述符,而不是 FILE*,因此需要查看 open 而不是 fopen,或者任何从 FILE* 获取 fd 的方法

于 2012-08-13T03:07:39.193 回答
0

您必须使用 fork() 进程并将其文件描述符重新分配给先前(手动)打开()的文件,或使用 system() 调用让 shell 为您处理它。

于 2012-08-13T03:13:29.430 回答