linux解譯器原理__linux

來源:互聯網
上載者:User

對於會shell編程的人肯定不會對#!/bin/sh感到陌生。這一行字串到底意味著什麼呢。

應該明確,所謂解譯器就是指#!行後面的可執行程式。

 

我們從exec函數說起。

exec函數總共包括六個函數。

#include <unistd.h>

int execl(const char *pathname,const char *arg0,.../*(char *)0 */);

int execv(const char *pathname,char *const argv[]);

int execle(const char *pathname,const char *arg0,.../*(char *)0,char *const envp[] */);

int execve(const char *pathname,char *const argv[],char *const envp[]);

int execlp(const char *filename,const char *arg0,.../*(char *)0 */);

int execvp(const char *filename,char *const argv[]);

 

這些函數作用都是一樣:執行一段新的代碼。

其中execl函數,第一個參數path是設定了執行位的可執行檔的路徑,後面的可變參數列表分別指向了傳遞給此執行檔案的參數列表,(包括了參數0,即是執行檔案的名稱),最後一個參數(char *)0則表示參數列表結束。

對於解譯器,exec函數(以execl為例)是這樣執行的,如果path是指向了一個指令碼,指令碼的第一行是以#!開頭,則這樣調用:

以#!後面的字串為命令,後面加上execl參數列表指定的參數,這樣就形成了新的程式的執行。

 

以下是unix進階環境編程中關於解譯器檔案的例子。

首先我們在/home/qiqijianglu下建立一個解譯器文本:

文本的名字為testinterp

文本裡的內容如下:

#!/home/qiqijianglu/echoarg foo

----------------------------------------------------------------------------

分隔線及分隔線以下不是文本裡的內容,echoarg程式內容如下:

#include "apue.h"

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

{

    int i;

    for(i=0;i<argc;i++)

    printf("argv[%d]: %s\n",i,argv[i]);

   exit(0);

}

-------------------------------------------------------------------------------

那麼echoarg就是一個解譯器,它回送每一個命令列參數。

下面我們要編寫一個執行一個解譯器檔案的程式,檔案名稱為197.c,代碼如下:

#include "apue.h"

#include <sys/wait.h>

int main(void)

{

     pid_t pid;

     if((pid=fork())<0)

     err_sys("fork error");

     else if(pid==0)

    {

        if(execl("/home/qiqijianglu/testinterp","testinterp","myarg1","MY ARG2",(char *)0)<0)

       err_sys("execl error");

    }

   if(waitpid(pid,NULL,0)<0)

   err_sys("waitpid error");

   exit(0);

}

---------------------------------------------------------------------------------------------------

這樣我們用命令cc 197.c編譯197.c,然後運行該程式./a.out

argv[0]: /home/qiqijianglu/echoarg
argv[1]: foo
argv[2]: /home/qiqijianglu/testinterp
argv[3]: myargl
argv[4]: MY ARG2

 

 

execl是這樣執行命令的:

/home/qiqijianglu/testinterp的內容是#!/home/qiqijianglu/echoarg foo則#!後面的字串/home/qiqijianglu/echoarg foo加上命令列參數列表組成了新的程式行/home/qiqijianglu/echoarg foo /home/qiqijianglu/testinterp myargl MY ARG2

注意,核心取execl調用中的pathname而非第一個參數testinterp,因為一般而言,pathname包含了比第一個參數更多的資訊。

對於testinterp指令碼,我們在shell中調用它時,shell會調用fork,exec,wait來執行它,首先,exec函數對#!行分析後得出此指令碼的解譯器為/home/qiqijianglu/echoarg,然後就把命令列處理成了/home/qiqijianglu/echoarg foo ./testinterp

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.