不管是直接cp還是先rm或者mv再cp,如果程式本身沒有重新load動態庫或者可執行檔案的功能,那麼只能通過重啟完成。
如果更新無所謂程式掛不掛,那無所謂了,直接cp就可以。
至於直接cp和先rm或者mv再cp的區別,看下文:
**:linux中替換執行中的程式或者so檔案導致的問題
參考博文
inode
在介紹問題之前,先簡單介紹一下linux中檔案的inode節點。
在linux中,每乙個檔案都有乙個inode節點,包含了檔案的元資訊,如下所示:
檔案的位元組數
檔案擁有者的user id
檔案的group id
檔案的讀、寫、執行許可權
檔案的時間戳,ctime, mtime 和 atime
鏈結數,即有多少檔名指向這個inode
檔案資料block的位置
可以使用 stat 檔名 檢視檔案的inode資訊
ls -i
df -i
stat filename12
3在linux中,每乙個檔案都有inode節點,每乙個inode節點都有乙個inode編碼,作業系統通過這個編碼來識別不同的檔案。表面上,是通過檔名開啟檔案,實際上,系統內部這個過程可分為三步:
系統找到這個檔案所對應的inode編碼
通過inode編碼獲取inode資訊
根據inode資訊,找到檔案資料所在的block,然後讀取資料。
替換執行程式
linux中由於demand paging(記憶體映像和需求分頁)機制的關係,必須確保正在執行的程式映象(並非檔案本身)不被而已破壞,因此核心在啟動程式後,會鎖定這個程式映象的inode。
當程式正在執行時,比如當前正在執行的程式名為test1,如果你使用
cp test2 test1
1的方法直接覆蓋正在執行的程式的話,會報錯,且提示file busy。這是因為cp命令並不是重新建立乙個新的檔案test1,而是開啟test2和test1,然後將test2的內容寫入到test1中,得到的新的test1檔案會繼承原test1檔案的屬性,inode編號不變,但是檔案大小和時間等資訊會發生改變,這就是說,改變了inode。但是程式是正在執行的,核心在程式啟動後就鎖定了程式映象的inode節點,所以這個cp命令會失敗。
strace cp test2 test1
1就可以發現這個命令底層系統呼叫的資訊。為了讓大家方便的看到,做乙個實驗,建立兩個內容不停的檔案,分別命名為test1和test2
stat test2
1檢視test2檔案的inode資訊如下所示
再檢視test1檔案的inode資訊
當使用cp test2 test1
1檢視test1檔案的inode資訊
當test1檔案被覆蓋之後,檔案大小發生了變化,但是inode編號並沒有發生變化,如果新建立了乙個檔案呢
cp test2 test
1檢視test檔案的inode資訊
新建立的test檔案的inode是新的節點,編號與之前都不相同。
所以,如果想替換正在執行的程式,需要先刪除檔案,然後在拷貝
rm test1
cp test2 test112
這樣才不會出現問題,這是因為cp和rm的差異造成的,cp覆蓋檔案,目標檔案會繼承原始檔的屬性,這就導致檔案的inode發生了變化,這是不允許的;但是如果先刪除目標檔案,新的檔案的inode已經發生了變化,而原inode資訊並沒有發生改變,它被核心所鎖定,直到核心釋放對它的引用。同理,使用mv只會修改檔名,並不會改變inode,新建立的檔案會使用新的inode,這兩種方法替換正在執行的程式都不會出錯。
mv test1 test_bak
cp test2 test112
替換so共享庫檔案
當乙個後台執行的程式,使用cp直接替換它引用的動態庫檔案時,會出現segmentation fault的錯誤,錯誤原因跟上面類似,可以採用rm + cp的方法替換,程式在執行過程中,如果刪除動態庫檔案並不會發生錯誤,此時,如果想讓新的動態庫檔案生效,還必須重新啟動程式。
linux原始碼包公升級程式
選項 a 將任何文件當作文字文件處理 b 忽略空格造成的不同 b 忽略空白行造成的不同 i 忽略大小寫造成的不同 n 當比較兩個目錄時,如果某個檔案只在乙個目錄中,則在另乙個目錄中視作空檔案 r 當比較目錄時,遞迴比較子目錄 u 使用同一輸出格式 我們舉乙個簡單的例子,來看看補丁是怎麼來的,然後應用...
C S程式自動公升級
c s程式自動公升級是乙個很重要的功能,原理其實很簡單,一般包含兩個程式乙個是主程式,也就是除了公升級功能以外的程式,另乙個就是公升級程式,常見的360,金山安全衛士都是這樣。一般服務端會有乙個配置檔案包含最新更新的檔案資訊的配置檔案,當然這些更新資訊也可以存到資料庫,或者其他地方。客戶端 也就是需...
程式更新,app公升級
程式更新 一 獲取程式的版本號 1.獲取包管理器 2.獲取到包的資訊 packageinfo info manager.getpackageinfo context.getpackagename 0 3.得到版本號 info.versioncode 二 判斷當前版本與線上版本是否一致,已經更新的內容...