在Linux中创建N个进程,并在当前目录中为每个进程创建一个文件

时间:2020-03-26 11:17:26

标签: c linux bash shell

我的工作是从Linux shell中使用N个参数(N个文件名)执行C程序。 我必须创建N个进程,并且必须为每个进程创建一个.bak文件,并使用参数中指定的文件名。

教授建议我们使用cp命令,但我不知道如何进行。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <limits.h>

typedef char stringa[80];
typedef stringa strvett[DIM];

void usage(char* prog_name) {
    fprintf(stderr,"Usage:\n\t%s: file1 file2 ... fileN dir_dest.\n", prog_name);
}

void main(int argc, char *argv[]) {
    int i = 0, j = 0, status, N = argc - 2, n_children = N;
    int[N] pid;
    char[N]* files;
    char[PATH_MAX - 1] wd;
    char term = '0';

    if (strcmp(argv[argc - 1], getcwd(wd, sizeof(wd)))) {
        fprintf(stderr, "Invalid directory.\n");
        usage(argv[0]);
        exit(EXIT_FAILURE);
    }
    for (i = 0; i < N; i++) {
        char[strlen(argv[i + 1])] files[i];
        strcpy(files[i], argv[i + 1]);
    }
    for (j = 0; j < n_children; j++ ) {
        pid[j] = fork();
        if (pid[j] == 0) {  // Executed by child
            if (term == '1') exit(0);
            else {
                term = '1';
                execl("/bin/ls", "ls", "-l", (char*)0);
//                cp command???
            }
        }
        else {
            if (pid[j] > 0) printf("%d: child created with PID %d\n", getpid(), pid[j]); // Executed by parent
            else {
                perror("Fork error");
                exit(1);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

下面的程序派生子进程,每个进程使用.bak命令创建一个cp文件,其名称与传递给程序的参数列表中指定的文件名相同。因为最后一个参数是dir_dest,所以我假设它是子进程用来创建.bak文件的目标目录。遵循程序的内联注释:

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

#define FL_EXTN ".bak"
#define PLEN 256
#define NLEN 64

void usage(const char* prog_name) {
    printf("Usage:\n\t%s: file1 file2 ... fileN dir_dest.\n", prog_name);
}

int main(int argc, char *argv[]) {
    char arg1[NLEN];
    char dir_dest[PLEN];

    // adding check for argc < 3, as it need minimum 2 arguments
    // a file_name and dir_dest
    if (argc < 3) {
        usage(argv[0]);
        exit(EXIT_FAILURE);
    }

    // add the command line argument validations
    // for e.g. dir_dest is valid or not

    strcpy (dir_dest, argv[argc - 1]);

    // run loop for argc - 2 time as the first argument is process name and 
    // last is dir_dest, rest are files to be copy with .bak extension
    for (int j = 0; j < argc - 2; j++) {
        // leaving it up to you to add a check whether file argv[j+1] 
        // exits or not. Below code is based on assumption that files exist
        strcpy (arg1, argv[j+1]);

        // fork child process
        pid_t child_pid = fork();
        if (child_pid == 0) { 
            // in child process
            char *cmdpath = "/bin/cp";
            char *cmd = "cp";
            char arg2[PLEN];

            // prepare the .bak file absolute path using dir_dest
            snprintf (arg2, PLEN, "%s/%s%s", dir_dest, arg1, FL_EXTN);

            // replace child process with cp
            execl(cmdpath, cmd, arg1, arg2, NULL);

            // get here only if execl fails
            perror("execl failed");

            // exit child process
            exit(1);
        } else {
            // in parent process 
            if (child_pid > 0) {
                printf("%d: child created with PID %d\n", getpid(), child_pid);
            } else {
                perror("Fork error");
                exit(1);
            }
        }
    }

    return 0;
}

其他:

不按照标准使用void作为main函数的返回类型。 main函数的返回类型应为int