日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 嵌入式 > 嵌入式軟件
[導(dǎo)讀] 1. 從一個(gè)問題開始首先要從項(xiàng)目中遇到的一個(gè)問題說起。編寫一個(gè)python文件test.py,文件test.py內(nèi)容如下:#! /usr/bin/python....如果在命令行方式執(zhí)行test.py的方式是:t

 1. 從一個(gè)問題開始

首先要從項(xiàng)目中遇到的一個(gè)問題說起。編寫一個(gè)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;

但是因?yàn)樾枰胑xec函數(shù)(這里使用execl)去調(diào)用這個(gè)python文件。在項(xiàng)目中是這樣寫的:

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

但執(zhí)行結(jié)果并不是預(yù)想的test.py執(zhí)行,而是啟動(dòng)了python交互程序,不知道是什么原因。因?yàn)橐恢币詾槿绻麑懸粋€(gè)C程序,比如main。那么在命令行輸入:main arg1 arg2執(zhí)行的效果和execl(”main”,”arg1”,”arg2”,(char*)0)的效果應(yīng)該是一樣的。

當(dāng)然同時(shí)伴隨我有另一個(gè)問題:

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

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

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

首先我們來分析一下在命令行執(zhí)行一個(gè)程序和通過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);

}

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

圖1

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

圖2

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

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

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

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

通過這個(gè)例子我們要有以下認(rèn)識(shí):

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

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

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

再運(yùn)行main,效果如圖3:

圖3

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

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

圖4

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

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

【問題】

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

【解決辦法】

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

3. 解釋器文件和解釋器[!--empirenews.page--]

先解釋兩個(gè)概念;解釋器文件和解釋器。

l 解釋器文件:一種文本文件,開頭通常是:#! pathname [option-argument];比較常見的是#! /bin/bash,shell腳本和python腳本都屬于解釋器文件。

l 解釋器:解釋器文件第一行中pathname指定的程序,如bash。

3.1 解釋器文件的執(zhí)行

當(dāng)執(zhí)行(exec)"解釋器"文件時(shí),exec系統(tǒng)調(diào)用會(huì)識(shí)別這種文件,內(nèi)核使調(diào)用exec函數(shù)的進(jìn)程實(shí)際執(zhí)行的并不是該"解釋器文件",而是pathname指定的解釋器。

我們可以自己寫一個(gè)解釋器,如之前所寫的foo.c:

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);

}

編譯成為foo然后保存在/mnt/hgfs/VWShared/。

下面我們?cè)谧约簩懸粋€(gè)”解釋器文件”——test:

l test

#!/mnt/hgfs/VWShared/foo

3.1.1 通過命令行執(zhí)行解釋器文件

直接在命令行中鍵入:”./test”,運(yùn)行test,效果如圖5。

圖5

將test內(nèi)容修改為:#!/mnt/hgfs/VWShared/foo argA argB,再次在命令行運(yùn)行test,效果如圖6。

圖6

通過這兩個(gè)例子,可以看出命令行運(yùn)行時(shí)當(dāng)執(zhí)行文件是”解釋器文件”時(shí),參數(shù)是如何傳遞給解釋器的:

(1) 通過執(zhí)行”解釋器文件”執(zhí)行解釋器,傳遞給解釋器的第一個(gè)參數(shù)是解釋器文件的pathname,即解釋器的路徑。

(2) “解釋器文件”中pathname后的可選參數(shù)(這里的argA,argB)如果存在的話會(huì)一起作為第二個(gè)參數(shù)傳遞給解釋器。

(3) “解釋器文件”名稱會(huì)作為下一個(gè)參數(shù)傳遞給解釋器。

3.1.2 通過execl執(zhí)行解釋器文件

接下來通過execl執(zhí)行解釋器文件test,修改main中的exec語句如下:

execl("/mnt/hgfs/VWShared/test","arg1",”arg2”,(char*)0));然后執(zhí)行main,效果如圖7。

圖7

從這個(gè)例子可以了解當(dāng)執(zhí)行文件是解釋器文件時(shí),內(nèi)核如何處理exec函數(shù)的參數(shù)及解釋器文件第一行的可選參數(shù)。我們知道執(zhí)行解釋器文件實(shí)際是執(zhí)行解釋器,由解釋器去讀取解釋器文件中的語句執(zhí)行,而第一行的pathname以#開頭在執(zhí)行時(shí)會(huì)被當(dāng)做注釋忽略。下面就讓我們分析一下最終傳入解釋器foo的參數(shù)都是什么。

(1) argv[0]是該解釋器文件的pathname;

(2) argv[1]是該解釋文件中的可選參數(shù);

(3) argv[2]是解釋器文件本身名字;

(4) argv[3]是execl出入的第二個(gè)參數(shù)(第一個(gè)參數(shù)是arg1)。

那么問題出現(xiàn)了,我們傳入execl的arg1去哪里了呢?其實(shí)這就是exec執(zhí)行”解釋器文件”和執(zhí)行一般程序的不同之處:在執(zhí)行一般程序時(shí),execl(const char* pathname,const char* arg0,...,(char*)0)中的arg0會(huì)被當(dāng)做執(zhí)行程序(pathname)的第一個(gè)參數(shù)argv[0],而在執(zhí)行解釋器文件時(shí),內(nèi)核取execl調(diào)用中的pathname而非第一個(gè)參數(shù)(arg0)作為第一個(gè)參數(shù)傳遞給解釋器,因?yàn)橐话愣?,第一個(gè)參數(shù)arg0通常是解釋器文件的名字,而pathname包含了比arg0更多的信息(解釋器文件的完整路徑)。所以當(dāng)execl執(zhí)行解釋器文件時(shí)第一個(gè)參數(shù)arg0是無效的。

為了說明這個(gè)問題,我們?cè)倥e一個(gè)例子,編寫python文件pyth.py如下:

l pyth.py:

#! /usr/bin/python

import sys

for i in range(0,len(sys.argv)):

print "argv[%d]: %s"%(i,sys.argv[i])

它的功能和foo一樣同樣是打印每個(gè)命令行參數(shù)。我們分別將main中的execl語句改為:

execl("/mnt/hgfs/VWShared/foo","arg1","arg2",(char*)0))和

execl("/mnt/hgfs/VWShared/pyth.py","arg1","arg2",(char*)0)),對(duì)比execl一般程序(foo)和解釋器文件(pyth.py)的效果如圖8、9。

圖8.execl("/mnt/hgfs/VWShared/foo","arg1","arg2",(char*)0))結(jié)果

圖9.execl("/mnt/hgfs/VWShared/pyth.py","arg1","arg2",(char*)0))結(jié)果

可以看出execl對(duì)于執(zhí)行普通文件和解釋器文件選取第一個(gè)參數(shù)是不同的。

3.2 execl執(zhí)行解釋器文件和命令行執(zhí)行解釋器文件的不同

我們上面已經(jīng)看到execl("/mnt/hgfs/VWShared/pyth.py","arg1","arg2",(char*)0))的結(jié)果(圖9),下面我們?cè)囈幌旅钚蟹绞剑簆yth.py arg1 arg2,結(jié)果圖10:

圖10

可以看到結(jié)果和通過execl執(zhí)行是有區(qū)別的,通過命令行執(zhí)行解釋器文件就像通過命令行執(zhí)行普通程序一樣,程序名稱作為第一個(gè)參數(shù),命令行后面依次作為后續(xù)參數(shù)。正因?yàn)閷?duì)于解釋器文件的execl方式和命令行方式執(zhí)行時(shí)選取第一個(gè)參數(shù)的方式不同,所以對(duì)于解釋器文件a.py:[!--empirenews.page--]

(1) 在命令行輸入:./a.py arg1 arg2;

(2) execl("./a.py","arg1","arg2",(char*)0));

(3) execl("./a.py",”xxx”,"arg1","arg2",(char*)0));

方式(1)和方式(2)不等價(jià),因?yàn)榉绞?1)中arg1會(huì)被當(dāng)做第二個(gè)參數(shù)傳遞給解釋器,而方式(2)中arg2會(huì)被當(dāng)做第二個(gè)參數(shù)傳遞給解釋器。方式(1)和方式(3)是等價(jià)的。

對(duì)于普通文件foo:

(1) 在命令行輸入: ./foo arg1 arg2;

(2) execl("./foo","arg1","arg2",(char*)0))

方式(1)和方式(2)是等價(jià)的。

4. 回答開始的問題

為了達(dá)到命令行方式:test.py arg1 arg2的效果,使用execl("test.py","arg1","arg2",(char*)0))肯定是不行的,因?yàn)閍rg1會(huì)被忽略,提示缺少參數(shù)。正確的方式是:execl("test.py",”xxx”,"arg1","arg2",(char*)0)),這里”xxx”代表任意字符串,不過一般會(huì)使用解釋器文件名,即”test.py”。

為了達(dá)到命令行方式:python test.py arg1 arg2的效果,使用execl("python",”test.py”,"arg1","arg2",(char*)0))也是不行的,因?yàn)閠est.py會(huì)被忽略,arg1會(huì)被當(dāng)做第一個(gè)參數(shù)傳給python解釋器。正確方式是:

execl(“python",”xxx”,”test.py”,"arg1","arg2",(char*)0)),這里”xxx”代表任意字符串,不過一般會(huì)使用解釋器文件名,即”test.py”。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀
關(guān)閉