首頁 > 軟體

Linux exec和source的簡單區別

2020-06-16 17:11:39

Linux種exec和.(Source)都可以同樣來執行程式或者指令碼,要區別二者區別,首先了解linux下的2種命令,內部命令和外部命令:

內部命令是特殊檔案格式.def實現的。

外部命令是通過系統呼叫或者獨立程式實現的。

其次shell執行指令碼的時候有兩種方式:

1、當前shell下執行

2、啟動子shell在子shell種執行

當shell啟動子shell時候,通過fork建立進程子進程,首先子進程會繼承父進程的很多屬性,而非共用,再複製了父進程資料之後,2者就基本沒有關係了,簡單表示就是 父進程屬性→子進程。fork函數和一般的函數不同,在他成功建立出子進程之後會返回兩個值,一個返回給父進程中的pid變數(值為子進程ID),一個返回給自進程中的pid變數(值為0)當然,如果fork失敗了,則只需要返回給父進程pid變數一個-1(子進程不存在)。子進程確實複製了父進程的資料,叫做繼承了父進程的部分屬性,這樣一來,子進程和父進程中的變數就不是同一個變數了。

 在shell種指令碼得的第一行通常是/bin/bash,這種方式就是使用subshell執行,見《shell指令碼程式設計》p36。當shell開啟一個可執行檔案時,系統呼叫fork建立進程,用於執行程式,核心執行飛編譯程式

返回錯誤"NOT excutable format file”,shell收到錯誤資訊啟動一個新shell(shell副本)來執行,

#!(shabang)用於告訴核心使用哪個shell來執行。

現在我們檢視系統幫助文件怎麼介紹的:

source(.):
Read and execute commands from  filename  in  the  current  shell
environment  and  return the exit status of the last command exe-
cuted from filename.
exec
If command is specified, it replaces the shell.  No  new  process
is  created.

由此可見source執行的時候是當前shell環境下執行,執行完成後把狀態返回給當前shell。

exec執行時候會關閉當年shell進程,並且fork一個相同pid的shell進程來執行,系統呼叫新的exec的process來替代原來的進程執行。從表面上看沒有新的進程建立,原來進程的程式碼段、資料段、堆疊都被新的process所代替。

 exec系統呼叫過程

fork()執行建立一個new_process,程式執行exec系統呼叫,fork()執行後父子進程共用程式碼段,資料空間分開,父進程copy自己的資料空間內容和上下文到子進程。採用寫時copy的策略:在建立子進程時不會不copy父進程的地址空間,共用,當子進程寫入資料時,這時候copy空間到子進程,這種策略提高效率並且執行fork()完執行exec後,子進程的資料會被新的進程代替。

 檔案描述符FD(file-descriptor)

檔案在開啟時候系統給每一個開啟的檔案分配用於維護的描述符,這通常包括系統開啟檔案描述符表,進程級的檔案描述符表(檔案操作符標誌和檔案控制代碼的參照),檔案系統i-node表。(以後會單獨寫一個對核心原始碼的解釋)

 exec的用法表(參考的百度)

exec cmd 執行cmd,結束後不反回原shell
exec <file file內容作為exec的stdin
exec >file exec中內容作為stdout
exec 3<file file內容讀到FD3中
sort <&3 FD3讀入內容被分類
exec 4>file FD4中內容寫入到file
cmd >&4 cmd輸出重定向到FD4
exec 5<&4 FD4走FD5的通道
exec 3<&- 關閉FD3

Example:

1、使用exec cmd

[yemo@localhost /]$ exec ls           #ls 替換掉當前shell進程
bin   dev  home  lib64       media  opt   root    selinux  sys  usr
boot  etc  lib   lost+found  mnt    proc  sbin srv  tmp  var
  
Connection closed by foreign host.    #shell已經被ls替代,ls執行完成進程結束退出
  
Disconnected from remote host(cent6mini_eth0) at 03:59:43.
  
Type `help' to learn how to use Xshell prompt.
[c:~]$

執行完成後關閉了shell

2、使用exec控制FD1(stdout)

[root@localhost tmp]# echo 'im lovin it'> echo.txt      #簡單的輸出重定向
[root@localhost tmp]# echo echo.txt
echo.txt
[root@localhost tmp]# ls /dev/fd/
0  1  2  3
[root@localhost tmp]# exec >echo.t             #把當前所有stdout定向到檔案
[root@localhost tmp]# ls
[root@localhost tmp]# echo "i did it"
[root@localhost tmp]# cat echo.txt
catecho.txt: input file is output file         #開啟會死迴圈系統保護           
[root@localhost tmp]# exec >/dev/tty            #把stdin重新定向會螢幕(tty裝置)
[root@localhost tmp]# cat echo.txt             #正常輸出內容
echo
echo.txt
haha
netstat
pass
rc
re.txt
sed_passwd
sudoers
yum.log
i did it

4、建立一個FD4

[root@localhost yemo]# ls /dev/fd/
0  1  2  3
[root@localhost tmp]# exec 4>4.txt                       #生成一個檔案描述符fd4指向檔案
[root@localhost tmp]# ls /dev/fd/       
0  1  2  3  4
[root@localhost tmp]# echo "i feel i lose my heart" >&4   #把流通過fd4到檔案中
[root@localhost tmp]# ls >&4       
[root@localhost tmp]# exec 4>&-                                 #關閉fd4
[root@localhost tmp]# cat 4.txt 
i feel i lose my heart
4.txt
echo
echo.txt
haha
netstat
pass
rc
re.txt
sed_passwd
sudoers
yum.log

exec建立FD4指向檔案4.txt,系統建立了FD4管道,通過管道4的內容到會傳到檔案4.txt中,關閉管道,否則檔案佔用無法開啟。

本文永久更新連結地址http://www.linuxidc.com/Linux/2017-07/145372.htm


IT145.com E-mail:sddin#qq.com