Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make script in linux use my interpteter and work? (#!)

Tags:

c

linux

shell

I've made a simple shell for linux. It's reading line by line with getline() until ctrl+d (eof/-1) is entered into standard input.

While entering into stdin line by line code like that:

ls -al &
ls -a -l

My shell works pretty well.

I've tried to run script through my shell, but it's not working. When I execute script, my shell is automatically executed (1st line) but the shell do not interprete other lines.

#!/home/arbuz/Patryk/projekt/a.out
ls -al &
ls -a -l

What could cause it? I have to say that I'm very beginner in linuxes and teacher didnt say anything about all that stuff. Just a homework. I've done some researches but that's all I've found.

Here's code of my Shell. I've added shell path into etc/shells but its still not working

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>

int main()
{

    ssize_t bufer_size = 0;
    char* line = NULL;
    int line_size;

    while ((line_size = getline(&line, &bufer_size, stdin)) != -1) // while end of file
    {
        char** words_array;
        words_array = (char**)malloc(200 * sizeof(char*));

        int words_count = 0;
        int i;
        int j = 0;
        int words_length = 0;
        char word[100];
        for (i = 0; i < line_size; i++)
        {
            if (line[i] == ' ' || line[i] == '\n')
            {
                words_array[words_count] = (char*)malloc(words_length * sizeof(char));
                int b;
                for (b = 0; b < words_length; b++)
                {
                    words_array[words_count][b] = word[b];
                }
                j = 0;
                words_count++;
                words_length = 0;
            }
            else
            {
                word[j] = line[i];
                j++;
                words_length++;
            }
        }

        bool run_in_background = false;

        if (words_array[words_count - 1][0] == '&')
        {
            run_in_background = true;
            words_array[words_count - 1] = NULL;
        }

        int a = fork();

        if (a == 0) // child process
        {
            execvp(words_array[0], words_array);
        }
        else       // parent process
        {
            if (run_in_background == true)
            {
                printf("\n ---- running in background. \n");
            }
            else
            {
                printf("\n ---- running normal \n");
                wait(NULL);
            }
        }
    }

    return 0;
}
like image 694
Patryk Avatar asked Nov 10 '12 12:11

Patryk


People also ask

How would you indicate which interpreter should be used to execute a script file?

#! is called the shebang when it occurs as the initial two characters on the initial line of a script. It is used in scripts to indicate an interpreter for execution.

How does script work in Linux?

script command in Linux is used to make typescript or record all the terminal activities. After executing the script command it starts recording everything printed on the screen including the inputs and outputs until exit.


2 Answers

Your shell must accept command line arguments. In this case, your program will be called like this:

/home/arbuz/Patryk/projekt/a.out your_script

So you'll need a main() of this signature:

int main(int argc, char* argv[])

and then parse the arguments. argc contains the amount of arguments. The script's filename is passed in argv[1]. You'll need to open it (using fopen()) and read commands from it instead of stdin. You should probably make sure that your shell ignores the first line of a file if it starts with a #.

If your script is called without an absolute path (a path that doesn't start with a /), then the filename is relative to the current directory. You can get that from the environment or programmatically with getcwd().

like image 83
Nikos C. Avatar answered Sep 21 '22 19:09

Nikos C.


The problem is that your shell reads from standard input, while a she-bang #! causes the script to passed as a command-line argument. So your shell is called as

/home/arbuz/Patryk/projekt/a.out <script>

... ignores the command line argument and waits for commands on standard input. You have to read the script from argv[1].

like image 29
Fred Foo Avatar answered Sep 23 '22 19:09

Fred Foo