2021-05-12 14:32:11
Linux exec和source的簡單區別
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
cat
:
echo
.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
相關文章