【问题标题】:Create N processes in Linux and create a file in the current directory for every process在Linux中创建N个进程,并在当前目录下为每个进程创建一个文件
【发布时间】:2020-07-07 00:17:29
【问题描述】:

我的作业是从 Linux shell 执行一个带有 N 个参数的 C 程序:N 个文件名。 我必须创建 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);
            }
        }
    }
}

【问题讨论】:

  • 当你在子进程 pid==0 时,你应该在那里创建文件
  • @Singh 好的,我该怎么做?我在网上浏览了一些文章,我找不到任何明确的内容
  • 这可能看起来像个傻瓜,但它(IMO)非常重要。不要打印使用说明和错误消息。用法语句NOT 是错误,并且将用法与错误一起打印会掩盖错误。 wrp.github.io/blog/2020/02/21/succinct-err-messages.html

标签: c linux bash shell


【解决方案1】:

以下程序分叉子进程,每个进程使用cp 命令创建一个.bak 文件,其名称与传递给程序的参数列表中指定的文件名相同。由于最后一个参数是dir_dest,我假设它是子进程创建.bak 文件的目标目录。按照程序的内联cmets:

#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。

【讨论】:

  • @ClarissaDeSimoni 你打算如何使用cp 命令创建文件?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 2014-09-11
  • 2021-03-26
  • 1970-01-01
  • 2014-04-12
  • 1970-01-01
相关资源
最近更新 更多