我为linux制作了一个简单的shell。它逐行读取getline(),直到ctrl + d(eof / -1)输入标准输入。
逐行输入stdin:
ls -al &
ls -a -l
我的shell工作得很好。
我试过通过我的shell运行脚本,但它不起作用。当我执行脚本时,我的shell会自动执行(第1行),但shell不会解释其他行。
#!/home/arbuz/Patryk/projekt/a.out
ls -al &
ls -a -l
可能导致什么?我不得不说我是linux的初学者而老师并没有对所有这些东西说什么。只是一个功课。我做了一些研究,但这就是我找到的。
这是我的Shell的代码。我已将shell路径添加到etc / shells中,但它仍然无法正常工作
#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;
}
答案 0 :(得分:12)
您的shell必须接受命令行参数。在这种情况下,您的程序将被调用如下:
/home/arbuz/Patryk/projekt/a.out your_script
所以你需要main()
这个签名:
int main(int argc, char* argv[])
然后解析参数。 argc
包含参数的数量。脚本的文件名在argv[1]
中传递。您需要打开它(使用fopen()
)并从中读取命令而不是stdin
。如果文件以#
开头,您应该确保shell忽略文件的第一行。
如果在没有绝对路径(不以/
开头的路径)的情况下调用脚本,则文件名相对于当前目录。您可以通过getcwd()
以编程方式从环境中获取该内容。
答案 1 :(得分:6)
问题是你的shell从标准输入读取,而she-bang #!
导致脚本作为命令行参数传递。所以你的shell被称为
/home/arbuz/Patryk/projekt/a.out <script>
...忽略命令行参数并等待标准输入上的命令。您必须从argv[1]
读取脚本。