1. 關於shell_exec的用法
exec()是用於執行shell命令的函數。它返回執行並返回命令輸出的最後一行,但你可以指定一個數組作為第二個參數,這樣輸出的每一行都會作為一個元素存入數組。使用方式如下:
1.代碼如下:
<?php
$last = exec('ls', $output, $return);
print_r($output);
echo "Return [$return]";
?>
2.假設ls命令在shell中手工運行時會產生如下輸出:
代碼如下:
$ ls
total 0
-rw-rw-r-- 1 chris chris 0 May 21 12:34 php-security
-rw-rw-r-- 1 chris chris 0 May 21 12:34 chris-shiflett
3.當通過上例的方法在exec()中運行時,輸出結果如下:
代碼如下:
Array
(
[0] => total 0
[1] => -rw-rw-r-- 1 chris chris 0 May 21 12:34 php-security
[2] => -rw-rw-r-- 1 chris chris 0 May 21 12:34 chris-shiflett
)
Return [0]
這種運行shell命令的方法方便而有用,但這種方便為你帶來了重大的風險。如果使用了被污染數據構造命令串的話,攻擊者就能執行任意的命令。
我建議你有可能的話,要避免使用shell命令,如果實在要用的話,就要確保對構造命令串的數據進行過濾,同時必須要對輸出進行轉義:
4.代碼如下:
<?php
$clean = array();
$shell = array();
/* Filter Input ($command, $argument) */
$shell['command'] = escapeshellcmd($clean['command']);
$shell['argument'] = escapeshellarg($clean['argument']);
$last = exec("{$shell['command']} {$shell['argument']}", $output, $return);
?>
2. 怎麼在linux中調用命令行中的命令,比如我想在一個程序中用命令行運行另一個程序
Linux編程中在命令行啟動另一個可執行文件或調用命令用system函數最簡單了,這個函數原理是在你編寫的那個程序的內部啟動另一個程序或命令,從而創建一個新進程,並等待這個進程執行完畢退出。如果正常執行,system函數將返回被執行程序或命令的退出碼;如果無法運行這個程序或命令,將返回錯誤代碼127;如果是其他錯誤,返回-1。這個函數的原型是:
#include <stdlib.h>
int system(const char *string);
參數string是將要執行的程序文件名或路徑,如果是啟動一個命令就是一個命令字元串。
還有一種執行外部程序的方法是exec系列函數,一般是在fork的子進程裡面調用exec系列函數,那主進程里直接調用exec系列不行嗎,為什麼要fork再在子進程里調用呢?因為exec系列的函數(包括execl函數)都是將當前進程替換成新進程,也就是說新進程啟動後原來的進程就不存在了,exec系列函數後面的那些代碼就不會再執行了。如果你不放在fork子進程裡面,那主進程在執行execl函數後就完全不存在了,所以exec系列函數的使用都是先fork然後在子進程裡面調用。因為exec系列函數都要使用fork調用,所以我一般是用system函數。
3. linux下exec 函數第一個參數和第二個參數的區別
哪裡寫的這些...好亂阿..
先解釋下基本的:
int main(argc,char * argv[])
main的參數,就是命令行參數.
比如你的可執行文件是test,你希望在程序執行時傳入IP地址,那麼可以這樣:
./test 127.0.0.1
此時,argc =1,argv[1]是就是指向"127.0.0.1"指針(命令參數全部當作字元串來處理的)。
而 argv[0]就代表第一個參數,這里對應的就是"./test"。
argc和argv在mian裡面都是可以使用的,出了main的范圍就不能使用了。
再來說你提出的第一個地方,exec的問題。
exec實際上包含了一組函數,execl, execlp, execle, execv, execvp, execvpe
具體使用方法,你man execv就可以得到這些函數的使用方法。
exec函數的作用是,產生一個新進程,結束當前進程(具體執行的操作是復制當前進程的一部分數據和許可權,然後根據參數啟動一個新的進程)。
exec這組函數執行時候,需要提供的參數包括:一個可執行程序的路徑,傳遞給可執行程序的參數。(這里的參數,與剛才說到的main的參數含義相同。)
說到這里應該明白了吧...就一個。
我不知道你要hello world干什麼...照你意思給寫了個.
第一個,就是你貼出來的代碼改動一點點(我這邊運行有點問題):
#include <stdio.h>
main(int argc,char* argv[])
{
int i=0
while(i<=argc)
{
printf("arguement %d : %s ",i,argv[i]);
printf("\n");
i++;
}
}
運行程序:
$gcc test.c -o test
$./test hello world
輸出結果:
[ksl@myhost WGX]$ ./test hello world
Arguement 0:./test
Arguement 1:hello
Arguement 2:world
Arguement 3:(null)
然後第二個,使用exec的例子,我用execl吧..
文件名是test1.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
void main(int argc,char *argv[])
{
printf("This is not exec...");
execl("./test","hello","world",NULL);
//如果exec執行正常,下面的printf將不會被執行
//因為當前進程已經結束,./test將被執行
printf("exec error");
}
輸出結果:
[ksl@myhost WGX]$ ./test1
Arguement 0:hello
Arguement 1:world
Arguement 2:(null)
後者並沒輸出"./test"....就是exec啟動的程序,其命令行參數中只有參數.(我也不曉得原因...=.=||)
4. linux下的命令都是干什麼用的
前三個和最後一個是兩個類型。前三個主要是Linux用來創建新的進程(線程)而設計的,exec()系列函數則是用來用指定的程序替換當前進程的所有內容。所以exec()系列函數經常在前三個函數使用之後調用,來創建一個全新的程序運行環境。Linux用init進程啟動其他進程的過程一般都是這樣的。
下面說fork、vfork和clone三個函數。這三個函數分別調用了sys_fork、sys_vfork、sys_clone,最終都調用了do_fork函數,差別在於參數的傳遞和一些基本的准備工作不同。可見這三者最終達到的最本質的目的都是創建一個新的進程。在這里需要明確一下,Linux內核中沒有獨立的「線程」結構,Linux的線程就是輕量級進程,換言之基本控制結構和Linux的進程是一樣的(都是通過struct task_struct管理)。
fork是最簡單的調用,不需要任何參數,僅僅是在創建一個子進程並為其創建一個獨立於父進程的空間。fork使用COW(寫時拷貝)機制,並且COW了父進程的棧空間。
vfork是一個過時的應用,vfork也是創建一個子進程,但是子進程共享父進程的空間。在vfork創建子進程之後,父進程阻塞,直到子進程執行了exec()或者exit()。vfork最初是因為fork沒有實現COW機制,而很多情況下fork之後會緊接著exec,而exec的執行相當於之前fork復制的空間全部變成了無用功,所以設計了vfork。而現在fork使用了COW機制,唯一的代價僅僅是復制父進程頁表的代價,所以vfork不應該出現在新的代碼之中。在Linux的manpage中隊vfork有這樣一段話:It is rather unfortunate that Linux revived this specter from the past. The BSD man page states: "This system call will be eliminated when proper system sharing mechanisms are implemented. Users should not depend on the memory sharing semantics of vfork() as it will, in that case, be made synonymous to fork(2)."
clone是Linux為創建線程設計的(雖然也可以用clone創建進程)。所以可以說clone是fork的升級版本,不僅可以創建進程或者線程,還可以指定創建新的命名空間(namespace)、有選擇的繼承父進程的內存、甚至可以將創建出來的進程變成父進程的兄弟進程等等。clone和fork的調用方式也很不相同,clone調用需要傳入一個函數,該函數在子進程中執行。此外,clone和fork最大不同在於clone不再復制父進程的棧空間,而是自己創建一個新的。
關於Linux命令的介紹,看看《linux就該這么學》,具體關於這一章地址3w(dot)linuxprobe/chapter-02(dot)html
5. 資料庫中的exec有什麼作用啊用來幹嘛的,什麼用,比如exec 表名 '1','','',''像這樣的格式
你舉得例子裡面,exec是執行資料庫中的存儲過程的。
exec+存儲過程名(不是表名)+'X'(X表示存儲過程所要的參數1……N;每個參數用","隔開)
比如有個尋出過程名叫getInfo,有2個輸入參數(id,name)
exec getInfo 『10000』,『張三'
結果就是getInfo這個存儲過程使用id='10000'、name='張三' 所得到的操作結果