2012-01-31 54 views
7
if (-e "$ENV{MYHOME}/link") { 
    system("rm $ENV{MYHOME}/link"); 
} 

這是用於檢查符號鏈接是否存在的代碼,如果存在,則將其刪除。如何使用Perl檢查並刪除符號鏈接(如果存在)?

我正在跟蹤此代碼無法運行的錯誤。我目前還無法弄清楚,但是發生的情況是這段代碼無法刪除符號鏈接,從而導致文件存在錯誤。

我想檢查這種技術是否存在一些根本缺陷?我還閱讀了關於http://perldoc.perl.org/functions/unlink.html,但想知道目前的方法是否由於某種原因不被推薦?

回答

19

只需使用的可能性:

if (-l "$ENV{MYHOME}/link") { 
    unlink "$ENV{MYHOME}/link" 
     or die "Failed to remove file $ENV{MYHOME}/link: $!\n"; 
} 

如果取消鏈接失敗時,它會說爲什麼。 -l詢問目標是否是鏈接。 -e詢問文件是否存在。如果你的鏈接是不存在的文件,它將返回false,你的代碼將無法刪除鏈接。

+0

確實'-l'檢查文件是符號鏈接還是硬鏈接?或兩者? – mask8 2014-06-06 06:15:03

+0

@ mask8 - 「-l」如果路徑是符號鏈接,則返回true。硬鏈接文件顯示爲常規文件,唯一不同的是它們的鏈接數(來自stat的st_nlink)大於1。目錄不能在Linux/Unix中被硬鏈接。 – unpythonic 2018-01-26 00:51:39

0

您的代碼將只具有所運行用戶的權限。這個符號鏈接是否可能由另一個用戶擁有,而且不可寫?

而且,總是有$ ENV {} MYHOME不包含你所想象的那樣......

+0

是的,這是我正在研究的一種可能性,這是可能的,但不應該發生。 – Lazer 2012-01-31 03:36:11

+0

順便說一下,取消鏈接的效率要高得多,因爲您不會分叉另一個進程。另外,我不知道你的系統負載有多重或發生的頻率如何,但分叉這樣的系統調用會打開類似於你的pid表的內容充滿並且無法分叉的可能性。 – 2012-01-31 04:03:52

0

各個操作系統都有自己的errno.h。我會用Errno.pm來處理每個錯誤。

use Errno; 
use File::Spec; 

my $dir = File::Spec->catfile($ENV{MYHOME}, 'link'); 

if (!unlink $dir) { 
    if ($! == Errno::ENOENT) { 
     die "Failed to remove '$dir'. File doesn't exist:$!"; 
    } 
} 
+0

倒退?爲什麼忽略「真實」的錯誤,只打印無關緊要的錯誤。 – ikegami 2012-01-31 06:46:44

+2

PS - '使用Errno;如果($!== Errno :: ENOENT)'也可以寫成'if($!{ENOENT})''。 – ikegami 2012-01-31 06:48:24

+0

感謝您的回覆,ikegami。真正的錯誤是區域敏感的,不適用於處理。無論如何,我不知道'%!'成語。 +1 – ernix 2012-01-31 14:40:03