link#
יוצר קישור קשיח מ־NEWFILE ל־OLDFILE הקיים.
link מוסיף רשומת ספרייה שנייה שמתייחסת לאותו קובץ בסיסי כמו OLDFILE. לאחר קריאה מוצלחת, לקובץ יש שני שמות: OLDFILE ו־NEWFILE. שני השמות הם אזרחים שווי־זכויות - הקובץ עצמו אינו נמחק עד שכל שם הוסר ואף תהליך אינו מחזיק את הקובץ פתוח. הקריאה היא עטיפה דקה סביב קריאת המערכת [link(2)] ויורשת את האילוצים שלה: שני הנתיבים חייבים להיפתר על אותה מערכת קבצים, ובמערכות POSIX רק ה־superuser רשאי ליצור קישור־קשיח לספרייה (רוב הקרנלים של Linux מסרבים אפילו ל־root).
תקציר#
link OLDFILE, NEWFILE
מה מקבלים בחזרה#
1 בהצלחה, 0 בכישלון. בכישלון, $! מוגדר לשגיאת המערכת - ערכים אופייניים הם EXDEV (קישור בין־התקנים), EPERM (היעד הוא ספרייה, או שמערכת הקבצים אוסרת קישורים קשיחים), EEXIST (NEWFILE כבר קיים), EACCES (הרשאה לא מספיקה), ו־ENOENT (OLDFILE חסר).
link $src, $dst
or die "link $src -> $dst failed: $!";
מצב גלובלי שהוא נוגע בו#
$!- מוגדר בכישלון לקוד שגיאת המערכת.
דוגמאות#
יצירת שם שני לקובץ קיים:
link "report.txt", "report.bak"
or die "link failed: $!";
שימוש ב־stat כדי לראות את מספר הקישורים עולה. האלמנט השלישי ברשימת stat הוא מספר הקישורים הקשיחים שמצביעים על ה־inode:
link "data", "data.alt" or die $!;
my $nlink = (stat "data")[3];
print "data has $nlink names\n"; # "data has 2 names"
החלפת קובץ באופן אטומי על־ידי בניית הגרסה החדשה תחת שם זמני, ואז החלפה עם link + rename:
open my $fh, ">", "config.new" or die $!;
print $fh $new_contents;
close $fh;
rename "config.new", "config" or die "rename: $!";
(לוריאנט באמת אטומי־תחת־קריסה תרצה link + unlink + rename; ראה את הפרשנות ב־perlport.)
זיהוי כישלון בין־התקנים ונפילה חזרה להעתקה:
use Errno qw(EXDEV);
unless (link $src, $dst) {
if ($! == EXDEV) {
# /tmp and $HOME are typically different filesystems
copy_file($src, $dst);
} else {
die "link $src -> $dst: $!";
}
}
מקרי קצה#
ספריות:
linkעל ספרייה נכשל עםEPERMלמעשה בכל מערכת מודרנית. POSIX אוסר זאת למי שאינו root, ו־Linux אוסר זאת אפילו ל־root. השתמש ב־symlinkכשאתה רוצה שם שני לספרייה.בין־מערכות־קבצים: הקרנל מחזיר
EXDEVאםOLDFILEו־NEWFILEנפתרים למערכות קבצים שונות. קישורים קשיחים אינם יכולים לחצות נקודות עיגון מכיוון שהם חולקים מספר inode, שמשמעותי רק בתוך מערכת קבצים אחת.יעד קיים: אם
NEWFILEכבר קיים, הקריאה נכשלת עםEEXIST.linkלעולם אינו דורס. הסר את היעד תחילה עםunlinkאם החלפה היא הכוונה.קישור סימבולי כ־
OLDFILE: הקישור נעשה ליעד של ה־symlink, לא ל־symlink עצמו, ברוב המערכות. אם אתה צריך לקשר את ה־symlink, dereference אותו במפורש או השתמש בפלטפורמה שחושפתlinkatעםAT_SYMLINK_FOLLOWמנוקה (אינו זמין דרך ליבת Perl).נתיבים יחסיים נפתרים מול ספריית העבודה הנוכחית ברגע הקריאה, עבור שני האופרנדים.
הרשאות:
linkאינו דורש הרשאת כתיבה עלOLDFILE- רק הרשאת חיפוש על הספרייה שלו והרשאת כתיבה על הספרייה המכילה אתNEWFILE.אותו נתיב בשני הצדדים:
link $f, $fנכשל עםEEXIST.unlink: הסרת
OLDFILEעםunlinkלאחרlinkמוצלח משאירה את הקובץ נגיש במלואו דרךNEWFILE. הנתונים משוחררים רק כאשר השם האחרון מבוטל ואף file descriptor פתוח אינו מתייחס אליו.ניידות: לא כל מערכת קבצים תומכת בקישורים קשיחים. FAT, exFAT, ומערכות קבצים רשת רבות מסרבות או מתנהגות בשקט כהעתקות. ראה
perlportלמטריצת הפלטפורמות.
הבדלים מהמקור#
תאימות מלאה עם Perl 5.42 המקורי.
ראו גם#
symlink- יוצר קישור סימבולי במקום קישור קשיח; עובד בין מערכות קבצים ועל ספריותunlink- מסיר רשומת ספרייה; הקובץ עצמו שורד כל עוד נשאר קישור אחר או descriptor פתוחrename- מעביר או משנה שם של קובץ בתוך מערכת קבצים אחת; אטומי במקום ש־link+unlinkאינםstat- בודק את מספר הקישורים (שדה 3) כדי לראות כמה שמות מתייחסים לאותו inode$!- שגיאת המערכת המוגדרת כאשרlinkמחזיר0