所以我在终端窗口中运行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_ */
我编译或运行程序错了吗?有什么我想念的吗?提前谢谢。
答案 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
。