Câu hỏi Làm thế nào để kiểm tra và xóa một liên kết tượng trưng nếu nó tồn tại, sử dụng Perl?


if (-e "$ENV{MYHOME}/link") {
    system("rm $ENV{MYHOME}/link");
}

Đây là mã được sử dụng để kiểm tra xem có tồn tại liên kết tượng trưng hay không và loại bỏ nó nếu nó có.

Tôi đang theo dõi một lỗi mà mã này không hoạt động. Tôi đã không thể tìm ra nó như bây giờ, nhưng những gì đang xảy ra là mã này là không thể loại bỏ các liên kết tượng trưng, ​​mà kết quả trong một 'File tồn tại' lỗi xuống dòng.

Tôi muốn kiểm tra nếu có một số lỗ hổng cơ bản với kỹ thuật này? Tôi cũng đọc về http://perldoc.perl.org/functions/unlink.html nhưng muốn biết nếu cách tiếp cận hiện tại không được khuyến cáo vì một lý do nào đó?


8
2018-01-31 03:31


gốc




Các câu trả lời:


Chỉ dùng:

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

Nếu hủy liên kết không thành công, nó sẽ nói lý do. Các -l hỏi nếu mục tiêu là một liên kết. Các -e hỏi xem tệp có tồn tại không. Nếu liên kết của bạn là một tệp không tồn tại, nó sẽ trả về false và mã của bạn sẽ không thể xóa liên kết.


22
2018-01-31 04:26



làm -l kiểm tra xem tệp có phải là liên kết tượng trưng hay liên kết cứng không? hoặc cả hai? - mask8
@ mask8 - -l nó trả về true nếu đường dẫn là một liên kết tượng trưng. Các tệp được liên kết cứng xuất hiện dưới dạng tệp thông thường, trong đó sự khác biệt duy nhất là số lượng liên kết của chúng ( st_nlink từ stat) lớn hơn một. Thư mục không thể được liên kết cứng trong Linux / Unix. - unpythonic


Mã của bạn sẽ chỉ có quyền của người dùng đang chạy. Có thể là liên kết tượng trưng được sở hữu bởi một người dùng khác và không thể ghi được?

Ngoài ra, luôn luôn có khả năng $ ENV {MYHOME} không chứa những gì bạn nghĩ là nó ...


0
2018-01-31 03:34



Vâng, đó là một khả năng tôi đang xem xét, điều này là có thể nhưng không nên xảy ra. - Lazer
BTW, unlink hiệu quả hơn nhiều khi bạn không bỏ qua quá trình khác. Ngoài ra, tôi không biết hệ thống của bạn được tải nặng như thế nào hoặc tần suất xuất hiện như thế nào, nhưng hãy gọi một cuộc gọi hệ thống như thế sẽ mở ra khả năng một cái gì đó giống như bàn pid của bạn đang đầy và không thể nĩa. - Victor Bruno


Các hệ điều hành tương ứng có hệ điều hành riêng errno.h. tôi sẽ dùng Errno.pm để xử lý từng lỗi.

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
2018-01-31 04:44



Ngược? Tại sao bỏ qua lỗi "thực" và chỉ in lỗi không quan trọng. - ikegami
PS - use Errno; if ($! == Errno::ENOENT) cũng có thể được viết if ($!{ENOENT}). - ikegami
Cảm ơn bạn đã trả lời, ikegami. Các lỗi thực là địa phương nhạy cảm và không phải để xử lý. Dù sao, tôi không biết %! cách diễn đạt. +1 - ernix
Ý tôi là bạn nên làm if ($! != Errno::ENOENT) { die ... }. Bạn đang làm ngược lại với những gì OP muốn làm. - ikegami