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;
}
#! 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.
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.
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()
.
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]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With