2010-03-06 180 views
3

如果應用程序正在運行其使用的其中一個共享庫被寫入或截斷,則應用程序將崩潰。移動文件或使用'rm'批量刪除文件不會導致崩潰,因爲操作系統(Solaris在這種情況下,但我認爲這在Linux和其他* nix上也是如此)足夠聰明,不會刪除與該文件在任何進程打開的時候。運行shell腳本時,如何防止覆蓋或截斷文件?

我有一個執行共享庫安裝的shell腳本。有時,它可能用於重新安裝已安裝的共享庫的版本,而無需首先卸載。由於應用程序可能正在使用已經安裝的共享庫,因此腳本非常聰明,可以將文件打包或移走(例如,當我們知道沒有應用程序時,cron可以清空的「已刪除」文件夾將運行),然後再安裝新的程序,以免它們被覆蓋或截斷。

不幸的是,最近一個應用程序在安裝後崩潰。巧合?很難說。這裏真正的解決方案是切換到一個比舊的巨型shell腳本更強大的安裝方法,但在交換機制作之前有一些額外的保護會很好。有沒有什麼方法可以包裝一個shell腳本以防止覆蓋或截斷文件(並且理想情況下會大聲地失敗),但仍然允許它們被移動或rm'd?

標準的UNIX文件權限不會做到這一點,因爲您無法區分移動/從覆蓋/截斷中刪除。別名可以工作,但我不確定整個命令是否需要別名。我想像truss/strace之類的東西,除非在每個動作之前檢查過濾器是否真的這樣做。我不需要一個完美的解決方案,甚至可以對付故意惡意的腳本。

+0

不提示這個問題不屬於堆棧溢出,但我想你可能會在Serverfault上得到一些有趣的和有用的輸入。 – Emily 2010-03-06 21:43:37

+0

是的,我在哪個網站發帖時發生衝突,shell腳本是重疊的網站。我會嘗試在那裏發帖,謝謝。 – 2010-03-07 01:44:59

回答

2

您可以通過

set noclobber 

防止由cp覆蓋等是很難阻止腳本通過I/O重定向覆蓋。我的意圖是重置PATH,使腳本與PATH一起運行,其中只包含一個條目,一個「有福」的目錄,您可以在其中放置您知道安全的命令。例如,這可能意味着您的cp版本始終安排使用--remove-destination選項(可能是GNU-ism)。在任何情況下,您都會安排腳本僅執行來自祝福目錄的命令。然後您可以單獨審覈每個這樣的命令。

如果您可以阻止腳本通過絕對路徑名執行命令,但我不知道如何執行該操作,那就太好了。如果您在常規目錄中進行安裝,那麼除非您進行大量環回安裝以使這些目錄可見,否則一個chroot監獄可能無濟於事。如果您要安裝的目錄包含危險的命令,我看不出完全保護自己的方式。

順便說一句,我試過並沒有得知如果install(1)在安裝前刪除了desitination。這將是學習的火花。

+0

這些都是偉大的建議。我很好奇安裝,因爲它是腳本使用的實用程序之一。 – 2010-03-06 23:14:23

+0

對於任何後來遇到這種情況的人:事實證明,GNU版本的安裝有一個--backup選項,用於對要被覆蓋的文件進行「備份」。它可能足夠精明,可以將現有文件壓縮到備份命名文件而不是複製副本,但我沒有檢查源代碼。 – 2010-03-07 01:46:30

1

我推測Bash腳本?劇本很長嗎?如果沒有,你可以手動完成:

if [ ! -f /tmp/foo.txt ] #If file does not exist 
then 
    ...code 
fi 

但我認爲你想要一種方法來包裝腳本。你當然可以使用strace來監視文件寫入,但是AFAIK它沒有中斷它們的功能,除非你設置了某種帶有規則的入侵檢測系統。

但是說實話,除非它是一個巨大的腳本,這可能是更多的麻煩比它的價值

0

編寫您自己的safe_install()函數,並確保它們是唯一使用的方法。如果您確實需要確定,請運行兩個進程。一個人有權進行更改,另一個人可以提早放棄所有權限,並告訴另一個腳本執行實際的磁盤工作。