LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   UNIX shell programming (https://www.linuxquestions.org/questions/programming-9/unix-shell-programming-87812/)

Tozilla 08-31-2003 10:23 PM

UNIX shell programming
 
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

SaTaN 08-31-2003 10:40 PM

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.

vanquisher 09-01-2003 03:32 AM

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...

Tozilla 09-01-2003 11:09 AM

Quote:

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

SaTaN 09-01-2003 11:12 AM

You are going on the right track .

If ever you need help with this , post a message .....

I'll be there to help you.

P.S :- Do you need help with strtok ??

Tozilla 09-01-2003 11:21 AM

Quote:

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?

thanks again

Tozilla 09-01-2003 11:23 AM

sorry..I clicked it wrong.

Quote:

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 =)

thanks again


SaTaN 09-01-2003 11:32 AM

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....

damocles 11-03-2005 11:01 PM

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.


thanks

smiswera 01-23-2006 05:11 AM

hai,

I need myshell.c program, anybody please help me for this

Francinoman 09-27-2006 10:41 PM

Hey guys,

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 :)

Francinoman 10-10-2006 05:45 AM

Hi guys,

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;

}


Francinoman 10-10-2006 10:16 PM

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?

9GB 10-11-2006 12:04 AM

Object not found
 
Quote:

Originally Posted by vanquisher
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 ... :scratch:
Are you sure it was the correct link?

Francinoman 10-11-2006 11:45 PM

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)


All times are GMT -5. The time now is 06:01 PM.