exec執行普通文件和解釋器文件的區別

2021-01-07 電子產品世界

1. 從一個問題開始

本文引用地址:http://www.eepw.com.cn/article/201609/304180.htm

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

#! /usr/bin/python

....

如果在命令行方式執行test.py的方式是:

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

但是因為需要,用exec函數(這裡使用execl)去調用這個python文件。在項目中是這樣寫的:

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

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

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

execl(「usr/bin/python」,」test.py」,(char*)0);和輸入命令」/usr/bin/python test.py」有什麼區別?

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

2. 命令行執行程序和exec執行程序的區別

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

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

l foo.c

#include

int

main(int argc,char* argv[])

{

int i;

for(i=0;i

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

exit(0);

}

再編寫main.c如下,將其編譯為可執行文件main,它使用execl調用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,結果如圖1:

圖1

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

圖2

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

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

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

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

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

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

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

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

再運行main,效果如圖3:

圖3

可以看到argv[0]變為了我們傳入的參數」xxxxx」。

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

圖4

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

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

【問題】

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

【解決辦法】

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

3. 解釋器文件和解釋器

相關焦點

  • Python IDE和解釋器的區別是什麼?
    經常會有剛剛入門Python的初學者把Python IDE與Python解釋器弄混,其實它們是有本質區別的,有些人還會誤認為配置Python環境就是配置IDE工具。那麼,Python IDE和解釋器的區別是什麼呢?
  • Linux系統利用可執行文件的Capability實現權限提升
    系統中,利用可執行文件的capabilities實現權限提升。libcap提供了getcap和setcap兩個命令來分別查看和設置文件的capabilities,同時還提供了capsh來查看當前shell進程的capabilities。libcap-ng更易於使用,使用同一個命令filecap來查看和設置capabilities。
  • Python程序執行過程與字節碼
    程序寫好後,只需敲下 python 命令,便可將程序啟動起來並開始執行:$ python some-program.py那麼,一個文本形式的 .py 文件,是如何一步步轉換為能夠被 CPU 執行的機器指令的呢?
  • python解釋器到底是什麼?
    解釋型語言VS編譯型語言 解釋型語言和編譯型語言的共同目標都是為了將我們所認識的語句(例如循環、判斷)轉成二進位代碼,再交給計算機執行。 二者之間最明顯的區別,編譯型語言就是指在我們把程序寫完之後,把代碼完全翻譯成二進位文件,通過執行該二進位文件來執行程序;而解釋型語言沒有轉二進位文件的過程,而是什麼時候需要,什麼時候編譯。有人說,這算什麼區別呢?還沒有說完,編譯型語言生成二進位文件後,那這個二進位文件就可以直接執行,而解釋型語言需要隨時帶著這個解釋器,必須隨叫隨到。
  • Python編譯器與解釋器
    對於Python語言,廣義上的「編譯器」,叫做解釋器。三、 編譯器與解釋器編譯器/解釋器:高級語言與機器之間的翻譯官都是將代碼翻譯成機器可以執行的二進位機器碼,只不過在運行原理和翻譯過程有不同而已。那麼兩者有什麼區別呢?用一個通俗的例子進行比喻:我們去飯館吃飯,點了八菜一湯。
  • Linux 文件和文件夾權限詳解
    Linux 文件和文件夾權限詳解一點PHP建站技術分享之linux權限探討,很多初學者只是在練習的時候使用過幾次命令,例如chmod又或者chown等,但是很少會在實際中會去關心這個問題,下面一點博主詳細給大夥分析linux
  • Java安全之命令執行
    知道了問題所在,解決辦法的思路就比較清晰了,可以把cmd做為啟動的指定模塊,然後以運行批處理的方式來達到命令執行,要以這樣的方式的話就必須啟動命令解釋器,就是在批處理的語句前面加上」/c」,最終的命令應該為「cmd /c echo xxx>test.txt」。OK,這回沒有拋出其他錯誤了,在本地的項目位置在找到了新創建的test.txt文件
  • 文本文件和二進位文件到底啥區別?
    :文件分為文本文件和二進位文件兩種。為什麼還有文本文件之說?文本文件難道最後不存儲為二進位嗎?剛學編程的很多同學都搞不清楚這個問題。文本文件最後當然也存儲為二進位,那它和二進位文件到底有什麼區別?或者說計算機又怎麼來區分文本文件和二進位文件呢?其實文本文件和二進位文件的區別不在於兩者的物理存儲,而是在於兩者對所存儲二進位數的邏輯解釋上。
  • 8.文件查找
    也就是說,使用which命令就可以看到某個系統指令是否存在,以及執行的命令位置。這個資料庫中含有本地所有文件信息。Linux系統自動創建這個資料庫,並且每天自動更新一次,因此,我們在用whereis和locate 查找文件時,有時會找到已經被刪除的數據,或者剛剛建立文件,卻無法查找到,原因就是因為資料庫文件沒有被更新。為了避免這種情況,可以在使用locate之前,先使用updatedb命令,手動更新資料庫。
  • Python中__init__.py文件的作用詳解
    當導入模塊時,解釋器按照sys.path列表中的目錄順序來查找導入文件。關於.pyc 文件 與 .pyo 文件.py文件的彙編,只有在import語句執行時進行,當.py文件第一次被導入時,它會被彙編為字節代碼,並將字節碼寫入同名的.pyc文件中。
  • 如何編寫和運行Python程序
    交互式解釋器會等待用戶輸入Python語句。輸入Python語句並回車,解釋器會執行語句並輸出結果。交互式解釋器是學習Python語言比較好的工具,優點是輸入Python語句可以立即得到反饋。在Windows環境下啟動交互式解釋器Windows啟動Python交互式解釋器有兩種方式。
  • 乾貨 | 深度辨析 Python 的 eval() 與 exec()
    2、exec 的基本用法語法:exec(object[, globals[, locals]])在 Python2 中 exec 是個語句,而 Python3 將其改造成一個函數,像 print 一樣。exec() 與 eval() 高度相似,三個參數的意義和作用相近。
  • 滲透測試中文件上傳技巧
    利用ffmpeg文件讀取/SSRF#EXTM3U#EXT-X-MEDIA-SEQUENCE:0#EXTINF:10.0,concat:http:#EXT-X-ENDLIST上傳imagemagic文件進行命令執行push
  • 深度辨析 Python 的 eval() 與 exec()
    文中,我提到過 eval() 和 exec() ,但對它們並不太了解。為了彌補這方面知識,我就重新學習了下。這篇文章是一份超級詳細的學習記錄,系統、全面而深入地辨析了這兩大函數。2、exec 的基本用法語法:exec(object[, globals[, locals]])在 Python2 中 exec 是個語句,而 Python3 將其改造成一個函數,像 print 一樣。exec() 與 eval() 高度相似,三個參數的意義和作用相近。
  • 常用的更改Linux系統文件權限的命令
    Linux作業系統中的文件或目錄的權限位是由 9 個權限位來控制,每三位為一組,它們分別是文件屬主(Ower)的讀、寫、執行,用戶組(Group)的讀、寫、執行以及(Other)其它用戶的讀、寫、執行;1、文件屬主: 讀r、寫w、執行x2、用 戶 組 : 讀r、寫w、執行x3、其它用戶: 讀r、寫w、執行x0
  • Python文件目錄操作就是這麼6
    ,並且將他保存進__builtin__._.指在python的交互式解釋器裡,』_』 代表上次你輸入得到的結果,hook是鉤子的意思,將上次的結果鉤過來sys.displayhook(value) #列印出給定的回溯和異常sys.stderr。
  • Linux刪除目錄下文件的10種方法
    刪除當前目錄下的文件1.rm -f *#最經典的方法,刪除當前目錄下的所有類型的文件2.find . -type f -delete或find .-type f -exec rm -f {} \;#用find命令查找普通文件並刪除or用find命令的處理動作將其刪除3.find . -type f | xargs rm -f#用於參數列表過長;要刪除的文件太多4.rm-f `find .
  • PHP通過header方式下載文件
    PHP通過header方式下載文件時,不能使用ajax方式提交,該方式會將header結果返回給ajax。(1) 在下載大文件的時候,通常需要很長的時間,PHP有默認執行時間,一般是30s,超過該時間,就是下載失敗,所以需要設置一下超時時間`set_time_limit(0);`該語句說明函數執行不設置超時時間。
  • Python 的 eval() 與 exec() 安全用法最佳實踐
    >>> result = eval('[].append(2)')>>> print(result)Noneexec() 函數的返回值只會是 None,與執行語句的結果無關,所以,將 exec() 函數賦值出去,就沒有任何必要。