<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > exec執(zhí)行普通文件和解釋器文件的區(qū)別

          exec執(zhí)行普通文件和解釋器文件的區(qū)別

          作者: 時間:2016-09-12 來源:網(wǎng)絡(luò) 收藏

          1. 從一個問題開始

          本文引用地址:http://www.ex-cimer.com/article/201609/304180.htm

          首先要從項目中遇到的一個問題說起。編寫一個python文件test.py,文件test.py內(nèi)容如下:

          #! /usr/bin/python

          ....

          如果在命令行方式執(zhí)行test.py的方式是:

          test.py -in inputfile -out outputfile;或python test.py -in inputfile -out outputfile;

          但是因為需要,用函數(shù)(這里使用l)去調(diào)用這個python文件。在項目中是這樣寫的:

          l(”test.py”,”-in”,”inputfile”,”-out”,”outputfile”,(char*)0);

          但執(zhí)行結(jié)果并不是預(yù)想的test.py執(zhí)行,而是啟動了python交互程序,不知道是什么原因。因為一直以為如果寫一個C程序,比如main。那么在命令行輸入:main arg1 arg2執(zhí)行的效果和execl(”main”,”arg1”,”arg2”,(char*)0)的效果應(yīng)該是一樣的。

          當然同時伴隨我有另一個問題:

          execl(“usr/bin/python”,”test.py”,(char*)0);和輸入命令”/usr/bin/python test.py”有什么區(qū)別?

          為了回答些問題,自己通過再反復(fù)看apue和做實驗測試,終于一點一點明白了,下面就來一點一點的分析。

          2. 命令行執(zhí)行程序和exec執(zhí)行程序的區(qū)別

          首先我們來分析一下在命令行執(zhí)行一個程序和通過exec函數(shù)執(zhí)行程序有什么區(qū)別,或者說需要注意的地方(一下所有編寫的文件都在/mnt/hgfs/VWShared/目錄下)。

          編寫程序foo.c如下,并編譯為可執(zhí)行文件foo。它打印參數(shù)列表(argv)的所有參數(shù).

          l foo.c

          #include

          int

          main(int argc,char* argv[])

          {

          int i;

          for(i=0;i

          printf(argv[%d]: %sn,i,argv[i]);

          exit(0);

          }

          再編寫main.c如下,將其編譯為可執(zhí)行文件main,它使用execl調(diào)用foo。

          l main.c

          #include

          #include

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

          {

          int n=0;

          if( (n=execl(/mnt/hgfs/VWShared/foo,(char*)0))==-1 )

          {

          perror(execl error);

          exit(0);

          }

          exit(1);

          }

          直接在命令行下運行foo,結(jié)果如圖1:

          圖1

          運行main(通過execl運行foo)結(jié)果如圖2:

          圖2

          可以看出直接在命令行運行foo,則”./foo”被當做argv[0],但是通過exec運行foo發(fā)現(xiàn)并沒有參數(shù)傳入foo(程序沒有任何輸出),也就是說argc值為0。這是什么原因呢?我們知道argv存放的是傳遞給main函數(shù)的命令行參數(shù),當在命令行鍵入”./foo”時,唯一的命令行參數(shù)”./foo”就被傳入給main的argv了。所以直接在命令行運行foo就打印出唯一的參數(shù)”./foo”。

          那么execl的情況呢?首先看一下execl的原型:

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

          注意到了吧,第一個參數(shù)是要執(zhí)行的程序名,第二個參數(shù)才是要傳入待執(zhí)行程序的第一個參數(shù),而上述main.c中沒有第二個參數(shù)(這里說的是execl的第二個參數(shù)),也就是沒有給foo傳遞任何參數(shù),foo的參數(shù)表argv當然就是空了,或者說argc為0。

          通過這個例子我們要有以下認識:

          argv[0]不一定就是所執(zhí)行程序的名稱,確切的說它只是命令行的第一個參數(shù),只是通常啟動程序是在命令行鍵入程序名稱啟動的,所以程序的名稱才成為argv[0]。但是也有情況argv[0]不是程序名稱的,如:

          (1) 通過exec執(zhí)行時,argv[0]是什么要視exec的參數(shù)來定。

          例如:我們將main中的execl語句改為:execl(/mnt/hgfs/VWShared/foo,xxxxx,(char*)0);

          再運行main,效果如圖3:

          圖3

          可以看到argv[0]變?yōu)榱宋覀儌魅氲膮?shù)”xxxxx”。

          (2) 通過程序別名啟動時,argv[0]就是程序的別名。如我們給foo創(chuàng)建一個軟連接sfoo,然后執(zhí)行sfoo效果如圖4:

          圖4

          可以看出輸出的argv[0]是./sfoo 而不是./foo,再次證明argv[0]是什么和程序名稱無關(guān),只是和傳入的命令行第一個參數(shù)有關(guān)。

          補充:在創(chuàng)建上述軟連接過程中遇到了一點小問題,不妨也在這里寫下來:

          【問題】

          在編譯VMware下的Linux系統(tǒng)對從Windows中共享過來的文件,進行編譯的時候,遇到:ln: creating symbolic link XXXXXX : Operation not supported

          【解決辦法】

          出現(xiàn)這類問題,主要是由于在編譯的時候,要用ln去建立一些軟鏈接,而這些文件是從Windows中,通過VMWare虛擬機共享進Linux的,而雖然此種操作在Linux系統(tǒng)中很常見,但Windows不支持,所以,編譯會報錯。比較方便的解決辦法是先將文件考到linux的其他目錄,再在其他非共享目錄中創(chuàng)建軟連接。另外還有個解決辦法就是,在VMWare下的Linux中,建立Samba服務(wù),然后新創(chuàng)建新samba用戶和文件夾,然后在windows中就可以訪問到該文件夾了。然后把在Linux中,從共享目錄拷貝到你所要共享的samba目錄中,這樣,也可以實現(xiàn)我們所要的文件共享。此時在去編譯這些代碼的時候,由于是在Linux系統(tǒng)中的,所以就OK了。

          3. 和解釋器


          上一頁 1 2 3 下一頁

          關(guān)鍵詞: exec 普通文件 解釋器文件

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();