尝试在终端中运行c程序时出现问题

时间:2017-04-30 23:03:55

标签: c linux shell unix terminal

所以我在终端窗口中运行c程序时遇到问题。我在Linux Mint上运行并尝试在终端窗口中编译和运行程序。我有3个文件:主文件(cShell.c),命令文件(commands.c)和命令文件(commands.h)的头文件。

它们列在下面。所有三个文件都位于同一个文件夹中,当我尝试运行时,它是终端中的工作目录。我可以使用以下语法成功编译程序 -

gcc *.c -o a.out

但是当我尝试使用" ./ cShell"来运行实际文件时我收到以下错误:

student@4720-devel ~/Desktop/cShell $ ./cShell.c
./cShell.c: line 8: syntax error near unexpected token `('
./cShell.c: line 8: `void print_user(void)'
student@4720-devel ~/Desktop/cShell $ 

cShell:

#include <stdlib.h>
#include <stdio.h>
#include "commands.h"



void print_user(void)
{
    char user[1024];
    if (getlogin_r(user, sizeof(user)) != 0) {
        fprintf(stdout, "User not found");
    }
    else {
    strcpy(user, getlogin());
    fprintf(stdout, "%s", user);
    }
}


void print_cwd(void)
{
    char cwd[1024];
    if (getcwd(cwd, sizeof(cwd)) == NULL) {
        fprintf(stdout, "CWD not found");
    }
    fprintf(stdout, "%s", cwd);
}

#define RL_BUFSIZE 1024
char *read_line(void)
{
  char *line = NULL;
  ssize_t bufsize = 0; // have getline allocate a buffer for us
  getline(&line, &bufsize, stdin);
  return line;
}


#define TOK_BUFSIZE 64
#define TOK_DELIM " \t\r\n\a"
char **split_line(char *line)
{
  int bufsize = TOK_BUFSIZE, position = 0;
  char **tokens = malloc(bufsize * sizeof(char*));
  char *token;

  if (!tokens) {
    fprintf(stderr, "lsh: allocation error\n");
    exit(EXIT_FAILURE);
  }

  token = strtok(line, TOK_DELIM);
  while (token != NULL) {
    tokens[position] = token;
    position++;

    if (position >= bufsize) {
      bufsize += TOK_BUFSIZE;
      tokens = realloc(tokens, bufsize * sizeof(char*));
      if (!tokens) {
        fprintf(stderr, "lsh: allocation error\n");
        exit(EXIT_FAILURE);
      }
    }

    token = strtok(NULL, TOK_DELIM);
  }
  tokens[position] = NULL;
  return tokens;
}

int launch(char **args)
{
  pid_t pid;
  int status;


//  if (execvp(args[0], args) == -1) {
//    perror("lsh");
//  }
//  return 1;

  pid = fork();
  if (pid == 0) {
    // Child process
    if (execvp(args[0], args) == -1) {
      perror("lsh");
    }
    exit(EXIT_FAILURE);
  } else if (pid < 0) {
    // Error forking
    perror("lsh");
  } else {
    // Parent process
    do {
      waitpid(pid, &status, WUNTRACED);
    } while (!WIFEXITED(status) && !WIFSIGNALED(status));
  }

  return 1;
}

int execute(char **args)
{
  int i;

  if (args[0] == NULL) {
    // An empty command was entered.
    return 1;
  }

  for (i = 0; i < num_builtins(); i++) {
    if (strcmp(args[0], builtin_str[i]) == 0) {
      return (*builtin_func[i])(args);
    }
  }

  return launch(args);
}

void loop(void)
{
  char *line;
  char **args;
  int status;

  do {
    print_user();
    printf("@");
    print_cwd();
    printf("> ");
    line = read_line();
    args = split_line(line);
    status = execute(args);

    free(line);
    free(args);
  } while (status);
}

int main(int argc, char **argv)
{
  // Load config files, if any.

  // Run command loop.
  loop();

  // Perform any shutdown/cleanup.

  return EXIT_SUCCESS;
}

commands.c:

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

int (*builtin_func[]) (char **) ;

/*
    get current user????!?!?
    o         ls
    o         stat
    o         timeout
    ·         grep
    ·         diff

x         clear
x         cat
x         cp
x         cd
x         mkdir
x         rmdir
x         sleep
x         kill
x         env
x         wait
 */

struct stat
{
    dev_t   st_dev;         /* inode's device */
    ino_t   st_ino;         /* inode's number */
    mode_t  st_mode;        /* inode protection mode */
    nlink_t st_nlink;       /* number of hard links */
    uid_t   st_uid;         /* user ID of the file's owner */
    gid_t   st_gid;         /* group ID of the file's group */
    dev_t   st_rdev;        /* device type */
    off_t       st_size;        /* file size, in bytes */
    time_t  st_atime;       /* time of last access */
    long        st_spare1;
    time_t  st_mtime;       /* time of last data modification */
    long        st_spare2;
    time_t  st_ctime;       /* time of last file status change */
    long        st_spare3;
    long        st_blksize;     /* optimal blocksize for I/O */
    long        st_blocks;      /* blocks allocated for file */
    u_long  st_flags;       /* user defined flags for file */
    u_long  st_gen;         /* file generation number */
};

struct dirent {
    unsigned long   d_fileno;   /* file number of entry */
    unsigned short  d_reclen;   /* length of this record */
    unsigned char   d_type;     /* file type, see below */
    unsigned char   d_namlen;   /* length of string in d_name */
    char                        d_name[255 + 1];    /* name must be no longer than this */
};

typedef struct DIR {
    char          *dirname;                    /* directory being scanned */
    struct dirent        current;                     /* current entry */
    int           dirent_filled;               /* is current un-processed? */
} DIR;

char *builtin_str[] = {
        "cd",
        "ls",
        "help",
        "exit",
        "mkdir",
        "rmdir",
        "stat",
        "cp",
        "cat",
        "clear",
        "sleep",
        "kill",
        "wait",
        "timeout",
        "env"

};

int num_builtins(void) {
    return sizeof(builtin_str) / sizeof(char *);
}

int _diff(char **args)
{
    if (args[1] == NULL || args[2] == NULL) {
        fprintf(stderr, "Expected 2 arguments to \"diff,\"\n");
    } else {
        wait(1);
    }
    return 1;
}

extern char **environ;
int _env(char **args)
{
    for (char **env = environ; *env; ++env)
        printf("%s\n", *env);
    return 1;
}

#define ESRCH 3
//ESRCH process does not exist
int _timeout(char **args)
{
    int exitstatus;
    if (args[1] == NULL || args[2] == NULL) {
        fprintf(stderr, "Expected 2+ arguments to \"timeout,\" duration, command, args[]\n");
    } else {
        int numArgs;
        numArgs = sizeof(args)/sizeof(char*);
        char* newArgs;
        newArgs = malloc(sizeof(char*)*(numArgs-2));

        for (int i = 2; i < numArgs; i++){
            newArgs[i-2] = args[i];
        }

        pid_t pid;
        pid = fork();
        if (pid == 0) {
            // Child process
          for (int i = 0; i < num_builtins(); i++) {
            if (strcmp(newArgs[0], builtin_str[i]) == 0) {
              return (*builtin_func[i])(newArgs);
            }
          }

            if (execvp(newArgs[0], newArgs) == -1) {
                perror("lsh");
            }
            exit(EXIT_FAILURE);
        } else if (pid < 0) {
            // Error forking
            perror("lsh");
        } else {
            // Parent process
            int duration;
            duration = atoi(args[1]);
            do {
                wait(1);
                duration -= 1;
            } while (duration > 0 && kill(pid, 0) != ESRCH);
            if (duration == 0  && kill(pid, 0) == ESRCH){
                kill(pid, 7);
                fprintf(stdout, "Timeout exceeded; Child pid %d killed.\n", pid);
            }
            else{
                fprintf(stdout, "Child pid %d completed in %d seconds..\n", pid, atoi(args[1])-duration);
            }
        }
        free(newArgs);
    }
    return 1;
}

int _wait(char **args)
{
    int exitstatus;
    if (args[1] == NULL) {
        fprintf(stderr, "Expected argument to \"wait\"\n");
    } else {
        exitstatus = wait(atoi(args[1]));
        fprintf(stdout, "Child process exit status: %d\n", exitstatus);
    }
    return 1;
}

int _kill(char **args)
{
    if (args[1] == NULL || args[2] == NULL) {
        fprintf(stderr, "Expected 2 arguments to \"kill\" - pid, signum\n");
    } else {
        if (kill(atoi(args[1]),atoi(args[2])) != 0) {
            perror("Error");
        }
    }
    return 1;
}

int _sleep(char **args)
{
    if (args[1] == NULL) {
        fprintf(stderr, "Expected argument to \"sleep\"\n");
    } else {
        if (sleep(atoi(args[1])) != 0) {
            perror("Error");
        }
    }
    return 1;
}

//doesn't work in debug; works in real term
int  _clear(char **args)
{
    const char *CLEAR_SCREEN_ANSI = "\e[1;1H\e[2J";
    write(fileno(stdout), CLEAR_SCREEN_ANSI, 12);
    return 1;
}

int _cat(char **args)
{
    FILE *read_this;
    if (args[1] == NULL) {
        fprintf(stderr, "Expected argument to \"cat\"\n");
    } else {
        read_this = fopen(args[1], "r");
        if (read_this == NULL) {
            fprintf(stderr, "Can't open input file\n");
            return 1;
        }
        char buf[BUFSIZ];
        while(NULL != fgets(buf, sizeof buf, read_this)) {
            printf("%s", buf);
        }
    }
    return 1;
}


#define O_RDONLY    0x0000      /* open for reading only */
#define O_WRONLY    0x0001      /* open for writing only */
#define O_RDWR      0x0002      /* open for reading and writing */
#define O_ACCMODE   0x0003      /* mask for above modes */
#define O_CREAT     0x0200      /* create if nonexistant */
#define O_TRUNC     0x0400      /* truncate to zero length */
#define O_EXCL      0x0800      /* error if already exists */
#define EINTR       4       /* Interrupted system call */

char *strcpy(char *d, const char *s)
{
    char *saved = d;
    while (*s)
    {
        *d++ = *s++;
    }
    *d = 0;
    return saved;
}

int _cp(char **args)
{
    if (args[1] == NULL || args[2] == NULL) {
        fprintf(stderr, "Expected 2 arguments to \"cp\"\n");
        return 1;
    }
    char* to;
    char* from;
    to = malloc(sizeof(args[2]));
    from = malloc(sizeof(args[1]));
    strcpy(to, args[2]);
    strcpy(from, args[1]);

    int errno;
    int fd_to, fd_from;
    char buf[4096];
    ssize_t nread;
    int saved_errno;

    fd_from = open(from, O_RDONLY);
    if (fd_from < 0)
        return -1;

    fd_to = fopen(to, "rb+");
    if( fd_to == NULL) {
        fd_to = fopen(to, "wb");
    }

    fd_to = open(to, O_RDWR | O_CREAT | O_TRUNC, 0777);
    if (fd_to < 0)
        goto out_error;

    while (nread = read(fd_from, buf, sizeof buf), nread > 0)
    {
        char *out_ptr = buf;
        ssize_t nwritten;

        do {
            nwritten = write(fd_to, out_ptr, nread);
            if (nwritten >= 0)
            {
                nread -= nwritten;
                out_ptr += nwritten;
            }
            else if (errno != EINTR)
            {
                goto out_error;
            }
        } while (nread > 0);
    }

    if (nread == 0)
    {
        if (close(fd_to) < 0)
        {
            fd_to = -1;
            goto out_error;
        }
        close(fd_from);
        free(to);
        free(from);
        /* Success! */
        return 1;
    }
    out_error:
    saved_errno = errno;
    close(fd_from);
    if (fd_to >= 0)
        close(fd_to);
    free(to);
    free(from);
    errno = saved_errno;
    perror("Error: ");
    return 1;
}

//fixme
int _stat(char **args)
{
    struct stat *buf;
    buf = malloc(sizeof(struct stat));
    if (args[1] == NULL) {
        fprintf(stderr, "Expected argument to \"stat\"\n");
    }
    else {
        if (stat(args[1], buf) != 0) {
            perror("Error: ");
        }
        else {
            long size = buf->st_blocks;
            fprintf(stdout, "%lu", size);
        }
    }
    //free(buf);
    return 1;
}

//fixme
int _ls(char **args)
{
    DIR *dp;
    struct dirent *ep;
    char cwd[1024];
    getcwd(cwd, sizeof(cwd));
    if (args[1] == NULL) {
        dp = opendir (cwd);
        if (dp != NULL)
        {
            while (ep = readdir (dp))
                fprintf(stdout, "%s\n", ep->d_name);
            (void) closedir (dp);
        }
        else
            perror ("Couldn't open the directory");
    }
    else {
        dp = opendir (args[1]);
        if (dp != NULL)
        {
            while (ep = readdir (dp))
                fprintf(stdout, "%s\n", ep->d_name);
            (void) closedir (dp);
        }
        else
            perror ("Couldn't open the directory");
    }
    fprintf(stdout, "%s\n");
    return 1;
}

int _rmdir(char **args)
{
    if (args[1] == NULL) {
        fprintf(stderr, "Expected argument to \"rmdir\"\n");
    } else {
        if (rmdir(args[1]) != 0) {
            perror("Error: ");
        }
    }
    return 1;
}

int _mkdir(char **args)
{
    if (args[1] == NULL) {
        fprintf(stderr, "Expected argument to \"mkdir\"\n");
    } else {
        if (mkdir(args[1]) != 0) {
            perror("Error");
        }
    }
    return 1;
}

int _cd(char **args)
{
    if (args[1] == NULL) {
        fprintf(stderr, "lsh: expected argument to \"cd\"\n");
    } else {
        if (chdir(args[1]) != 0) {
            perror("Error");
        }
    }
    return 1;
}

int _help(char **args)
{
    int i;
    for (i = 0; i < num_builtins(); i++) {
        printf("  %s\n", builtin_str[i]);
    }
    printf("Use the man command for information on other programs.\n");
    return 1;
}

int _exit(char **args)
{
    return 0;
}

int (*builtin_func[]) (char **) = {
        &_cd,
        &_ls,
        &_help,
        &_exit,
        &_mkdir,
        &_rmdir,
        &_stat,
        &_cp,
        &_cat,
        &_clear,
        &_sleep,
        &_kill,
        &_wait,
        &_timeout,
        &_env,
};

commands.h:

#ifndef COMMANDS_H_
#define COMMANDS_H_

int cd(char **args);
int ls(char **args);
int help(char **args);
int shell_exit(char **args);
int num_builtins(void);

char *builtin_str[];
int (*builtin_func[]) (char **);

#endif /* COMMANDS_H_ */

我编译或运行程序错了吗?有什么我想念的吗?提前谢谢。

2 个答案:

答案 0 :(得分:0)

"gcc *.c -o a.out". However when I attempt to run the actual file using "./cShell"

-o a.out表示将编译的输出写入名为a.out的文件(无论如何这是默认值,因此您可以将其保留)。

但是,您尝试运行./cShell.c(或./cShell - 您的问题在不同的部分都有说明)?您刚刚编译了cShell.c - 所以现在要执行它(而不是编译版本)?这不是它的工作方式。

尝试gcc *.c -o cShell然后./cShell(注意,不是cShell.c)

答案 1 :(得分:0)

使用

进行编译
gcc MyProgram.c -o MyProgram

然后

./MyProgram

确保您对源文件和输出文件拥有足够的权限。用

检查
ls -la

您希望在源文件中看到类似的内容:

-rw-rw-r-- 1 user user < stuff you dont need now > MyProgram.c
对于编译的输出文件,

等等:

-rwxrwxr-x 1 user user < stuff you dont need now > MyProgram*
                                                   this star means 
                                               this file is executable

如果不这样做,请使用chmod更改权限。 chmod具有以下语法(当然有一个手册页)

chmod 0775 MyProgram

其中0定义八进制represantation输入,其余数字引用user group other。鉴于您是当前尝试运行MyProgram的用户,您只需依靠chmod 0744 MyProgram执行它('。/ MyProgram',因为您在其所在的文件中)。< / p>

您可以在线和手册页找到更多chmod