ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm trying to write a problem in C which can display a prompt,e.g My_shell$ and accept a command entered by the user by using fgets. Also, it needs to execute the command by invoking fork() and execvp() system call. Then, if user type "logout", the shell should exit.
My problem is that I don't know how to combine fgets, fork() and execvp() together inside the program.
Can anyone please show me some examples or suggestions?
Thank you
In a while loop
{
First accept the input using fgets .....
Use strtok to split the fgets into arguments for use in execvp()
Check if command is "logout" and exit from the program .
Then fork to create a child .
In the child process , use exec to run the command requested by the user
In the parent , wait until the child has exited n then print
"Command successful or something "
}
I suppose this should do it for you unless u want to include background , redirection and other stuff....
If you still aren't able to get it I'll post the program.
hey, i wrote this program just a few weeks ago for my OS course. it is online at http://gdit.iiit.net/~vamsee_k/myshell.c
hope it helps you out. it supports redirection but doesn't run a process in the background( the `&' thing ). Hope it helps you out...
Originally posted by SaTaN In a while loop
{
First accept the input using fgets .....
Use strtok to split the fgets into arguments for use in execvp()
Check if command is "logout" and exit from the program .
Then fork to create a child .
In the child process , use exec to run the command requested by the user
In the parent , wait until the child has exited n then print
"Command successful or something "
}
I suppose this should do it for you unless u want to include background , redirection and other stuff....
If you still aren't able to get it I'll post the program.
Welcome to LQ.
Thank you for replying me...I forgot something that I also need to take care of the background like '&' in my program.
I've already startd a little bit. But I did differently from what you wrote. In my program , I used functions and still don't know how to implement fgets() in the UNIX environment. Can you take a look at it and give me some suggestions?
Thank you
Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main();
void parent(int pid);
void child();
int main()
{
int ret;
if( (ret=fork()) > 0 )
parent(ret);
else if ( ret == 0 )
child();
else
perror("fork() failed");
exit(0);
}
void parent(int pid)
{
int child_ExitVal;
/*The parent only invokes the wait() if the command is a foreground command,** i.e. there is no '&' at the end of the line*/
if (wait(&child_ExitVal) < 0
{ perror("wait");
exit(1);
}
}
void child()
{
char *argv[100];
/*this part should use strtok. But I read it from the Unix manual, I'm still unable to manipulate the command typed in so that it is usable by execvp.*/
argv[0] = "ls";
argv[1] = "-l";
argv[2] = "/";
argv[3] = NULL;
execvp(argv[0], argv);
/* If the program arrives here, an error must have occurred otherwise a different program image would be active.*/
perror("execvp");
exit(1);
}
To vanquisher:
I found little bit hard to follow your program. Can you explain your program to me please? Also, unforunately, I need to run a process in the background (the '&' thing). Can you tell me how to implement into my above code.
Thank you
Originally posted by SaTaN You are going on the right track .
If ever you need help with this , post a message .....
I'll be there to help you.
I'm still reading a UNIX tutorial how to use fgets() in the UNIX. I'm confused how to use it. Because I need to accept a command entered by user using fgets(). Should I use printf() to prompt user to enter a command and invoke the fork() and execvp() in the main function? can you show me a useful example for it?
Originally posted by Tozilla I'm still reading a UNIX tutorial how to use fgets() in the UNIX. I'm confused how to use it. Because I need to accept a command entered by user using fgets(). Should I use printf() to prompt user to enter a command and invoke the fork() and execvp() in the main function? can you show me a useful example for it?
P.S I'm still reading about that strtok command. Maybe, let me have more understanding of it. If I still don't undertand how to implement it, then I'll post the message to ask you for help =)
Yeah you can use printf to print the prompt .....
After that you can use either "scanf or fgets"
The problem with scanf is that the default delimiter is " " and
so for an input of "ls -l -a --color" only "ls" will be stored in the var
So u need to use
scanf("%[^\n]",string);
Here we have are going to accept characters until a "\n" is encountered
Check man scanf for more details
In case of fgets the syntax is as follows
fgets(buf,MAX_SIZE,stdin);
where buf is a character array , MAX_SIZE is the maximum no. of characters you want to accept , stdin for reading from the stdin
You can use either of these for reading for your shell program....
Hello
I am new to shell programmin and need to learn how to implement a simple unix shell. Any help(code sinppets,learning material etc) would be greatly appreciated.
Just so you know I am just about to start working on a very similar if not the same project.
I have done alot of research and looking on forums such as this one, and I see alot of the people creating a shell using C are students. I am no different :P This is a project that I have chosen to take up.
So I have read alot of the questions and answers on this subject and it all seems very helpful. So im already thankful to all the people that have helped me with out even knowing.
I have alot of idea's on how i will implement this, and I will work on this throughout the next month and keep everyone updated with anything I learn... or any problems I have
Last edited by Francinoman; 09-27-2006 at 10:45 PM.
Well here is my first update of code. Anyone can use it, and i would be very thankful for any experts to look at my code and suggests improvments. Of course its not finished yet, but it does have the basic functionality of:
ls with args
mkdir
rmdir
most basic shell commands except cd
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h> // Mainly for strtok
#define MAX_ARGS 2
char * PATH = "MyShell:$:";
char *path; //for the command path
typedef struct{
char *cmd_path; //path of command
int argc; //number of args for the cmd
char *argv[MAX_ARGS];
char cmd_suffix;
}commandStruct;
int runCommand(commandStruct * command1);
int main() {
system("clear");
int flag = 1;
do {
char buffer[256], *input;
pid_t child;
int childstatus, status; //For Fork
int x = 1;
char *cmd; //For strtok
char *command; //The command
int cmdlen;
commandStruct *command1 = (commandStruct*) malloc(sizeof(commandStruct));
command1->argc = 1;
printf("\n%s", PATH);
fflush(stdout);
input = fgets(buffer, 256, stdin);
cmdlen = strlen(input); //Take out new line char
if (input[cmdlen-1] == '\n') { //
input[cmdlen-1] = '\0'; //
} //
//Get first token (the command) from input
cmd = strtok(input, " ");
command = cmd;
if (strcmp(command, "exit") == 0){
flag = 0;
}
command1->cmd_path = command;
command1->argv[0] = command1->cmd_path;
//Loop thru until whole command is tokenized
while (1)
{
//Check command has no more than 2 args
if (command1->argc > 3) {
printf("\nError! Too many command arguements!\n");
break;
}
//Extract next part of command
cmd = strtok(NULL, " ");
//Check that there is nothing else to extract
if (cmd == NULL)
{
//printf("Command Tokenised");
break;
}
command1->argv[command1->argc] = cmd; //put arg into arg array
command1->argc = command1->argc+1; //increase count of args
}
printf("Number of args: %d\n", command1->argc);
childstatus = fork();
if (childstatus != 0) { //if parent process is running
wait(&status);
} else {
/* This area is child process */
runCommand(command1);
return(0);
}
}while (flag == 1);
return 0;
exit(0);
}
int runCommand(commandStruct * command1) {
printf("Command: %s\n", command1->cmd_path);
execvp(command1->cmd_path, command1->argv);
//printf("%s\n%s\n%s\n", command1->argv[0], command1->argv[1], command1->argv[2]);
return 1;
}
The first problem I had was actually getting commands that were input to run. But that was fixed however i think it might be a bit dodgy? What i actually did was the array of arguements for execvp() did not include the command as the first entry of the array. Once the first entry of this array was set to the command, and the arguments were set to the following array entries, the execute function seemed to work fine.
So the next step in my shell is to allow directory walking with the chdir() command... which i am having trouble with and researching. And also to add redirection of input and output.
If anyone has any tips on either of these, that would be great! :P
And this might be getting ahead of myself, but does anyone know much about changing the colour of the text output? Or perhaps making the output bold?
Last edited by Francinoman; 10-10-2006 at 10:17 PM.
hey, i wrote this program just a few weeks ago for my OS course. it is online at link
hope it helps you out. it supports redirection but doesn't run a process in the background( the `&' thing ). Hope it helps you out...
The link is not working i suppose ...
Are you sure it was the correct link?
yeah, i also tried to look at that and the link seemed broken.
So now i have fixed my code so the ability to walk thur directories is now complete.
Now my shell has most basic functions including exit and cd and generally acts as a shell (Even a function to change the shell prompt!!! hehe). From there I am going to add in re-direction... then see where i get from there.
is it strange that i am enjoying this project? (no im not a nerd! :P)
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.