如何在linux中制作脚本使用我的interpteter并工作?(#!)

Pat*_*ryk 8 c linux shell

我为linux做了一个简单的shell.它与getline()逐行读取,直到ctrl + d(eof/-1)进入标准输入.

在进入stdin时,逐行代码:

ls -al &
ls -a -l
Run Code Online (Sandbox Code Playgroud)

我的shell工作得很好.

我试图通过我的shell运行脚本,但它不起作用.当我执行脚本时,我的shell会自动执行(第1行),但shell不会解释其他行.

#!/home/arbuz/Patryk/projekt/a.out
ls -al &
ls -a -l
Run Code Online (Sandbox Code Playgroud)

什么可能导致它?我不得不说我是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;
}
Run Code Online (Sandbox Code Playgroud)

Nik*_* C. 12

您的shell必须接受命令行参数.在这种情况下,您的程序将被调用如下:

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

所以你需要一个main()这样的签名:

int main(int argc, char* argv[])
Run Code Online (Sandbox Code Playgroud)

然后解析参数.argc包含参数的数量.传入脚本的文件名argv[1].您需要打开它(使用fopen())并从中读取命令而不是stdin.你可能应该确保你的shell忽略文件的第一行,如果它以a开头#.

如果在没有绝对路径(不以a开头的路径)的情况下调用脚本/,则文件名相对于当前目录.您可以从环境或以编程方式获取getcwd().

  • 他还必须告诉他的解析器忽略shebang(并且通过扩展,任何以`#`开头的行) (6认同)

Fre*_*Foo 6

问题是你的shell从标准输入读取,而she-bang #!导致脚本作为命令行参数传递.所以你的shell被称为

/home/arbuz/Patryk/projekt/a.out <script>
Run Code Online (Sandbox Code Playgroud)

...忽略命令行参数并等待标准输入上的命令.你必须从中读取脚本argv[1].