readlink#
החזרת נתיב היעד שאליו מצביע קישור סימבולי.
readlink שואל את הקרנל איזו מחרוזת מאוחסנת בתוך קישור סימבולי, מבלי לעקוב אחריו ומבלי לגעת בקובץ שהקישור מפענח אליו בסופו של דבר. הארגומנט הוא נתיב הקישור עצמו; ערך ההחזרה הוא מחרוזת היעד הגולמית כפי שנרשמה כאשר הקישור נוצר. אם EXPR מושמט, נעשה שימוש ב־$_.
תקציר#
readlink EXPR
readlink
מה מקבלים בחזרה#
בהצלחה, יעד הקישור כמחרוזת - בדיוק הבתים המאוחסנים ב־symlink, ללא פירוש כלשהו. בכישלון, undef, כאשר $! מוגדר לשגיאת המערכת. קודי שגיאה אופייניים:
EINVAL- הנתיב קיים אך אינו קישור סימבוליENOENT- הנתיב אינו קייםEACCES- רכיב ספרייה אינו ניתן לחיפושELOOP,ENAMETOOLONG,ENOTDIR- כשלי פענוח־הנתיב הרגילים על רכיבים המובילים לקישור
המחרוזת המוחזרת אינה קנונית ואינה הופכת למוחלטת. קישור שנוצר עם ln -s ../lib/libfoo.so libfoo.so מחזיר את הליטרל "../lib/libfoo.so", יחסי לספרייה המכילה את הקישור עצמו - לא לספריית העבודה הנוכחית. פענוח היעד לנתיב אמיתי ומוחלט הוא עבודת הקורא; ראו Cwd::abs_path.
מצב גלובלי שהוא נוגע בו#
דוגמאות#
קריאת יעד קישור באופן ישיר:
my $target = readlink "/usr/bin/vi";
print defined $target ? "points to $target\n" : "not a symlink: $!\n";
צורת ברירת המחדל של הארגומנט בתוך לולאה על שמות קבצים:
for (@paths) {
next unless -l; # skip anything that isn't a symlink
my $t = readlink; # reads $_
print "$_ -> $t\n" if defined $t;
}
הגנו במפורש מפני לא־symlink־ים. readlink על קובץ רגיל מחזיר undef ומגדיר את $! ל־EINVAL:
my $t = readlink $path;
if (!defined $t) {
die "readlink $path: $!" unless $!{EINVAL};
# not a symlink - handle as a plain file
}
פענחו יעד קישור יחסי מול ספריית הקישור עצמו, שהיא הבסיס הנכון - לא ספריית העבודה הנוכחית:
use File::Basename qw(dirname);
use File::Spec;
my $target = readlink $link // die "readlink $link: $!";
my $resolved = File::Spec->rel2abs($target, dirname($link));
קנוניזו במלואו (עקבו אחר כל קישור בשרשרת, כווצו . ו־.., יצרו נתיב מוחלט) באמצעות Cwd::abs_path:
use Cwd qw(abs_path);
my $real = abs_path($link); # undef if any component is missing
מקרי קצה#
לא symlink:
readlinkעל קובץ רגיל, ספרייה, או כל דבר אחר שאינו קישור סימבולי מחזירundefומגדיר את$!ל־EINVAL. בדקו עם-lתחילה אם רוצים להבחין בין ״לא קישור״ לבין שגיאות אחרות.נתיב חסר: רכיב של
EXPRשאינו קיים נותןENOENT, זהה לכל כשל אחר של חיפוש־נתיב.ארגומנט ברירת מחדל:
readlinkחשוף משתמש ב־$_. לא נפלטת אזהרה כאשר$_הואundef; הקריאה פשוט נכשלת עם שגיאת חיפוש־נתיב.רכיבים נגררים:
readlinkפועל רק על הרכיב הסופי - symlink־ים אמצעיים בנתיב נעקבים כרגיל.readlink "/a/b/c"כאשר/aעצמו הוא symlink, קורא את הקישור ב־c, לא ב־a.יעד יחסי, ללא שינוי: המחרוזת המוחזרת מאוחסנת מילולית. אל תניחו לעולם שהמחרוזת מוחלטת, ולעולם אל תצרפו אותה לספריית העבודה הנוכחית - צרפו אותה לספרייה המכילה את הקישור, או הזינו את נתיב הקישור (לא את היעד) ל־
Cwd::abs_path.קישורים תלויים באוויר: קישור שיעדו אינו קיים עדיין נקרא כראוי.
readlinkאינו מבצע stat על היעד. השתמשו ב־lstatלבחינת הקישור עצמו, ב־statלבחינת מה שאליו הוא מצביע (ויכשל אם היעד חסר).פלטפורמות ללא symlink־ים: במערכות שאינן ממשות קישורים סימבוליים,
readlinkמעלה חריגה במקום להחזירundef. ל־Linux (היעד היחיד הנתמך של pperl) תמיד יש אותם, כך שזה רלוונטי רק לקוד נייד שמשותף עם יעדים אחרים.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
symlink- יצירת קישור סימבולי; פעולה הפוכהlink- יצירת קישור קשיח (לא ניתן לקריאה עםreadlink; קישורים קשיחים אינם ניתנים להבחנה מהשם המקורי)lstat-statל־symlink עצמו ולא ליעדו; השתמשו יחד עםreadlinkלבחינת קישור באופן מלא-l- מבחן קובץ עבור ״האם זהו קישור סימבולי״; בדקו לפני קריאה ל־readlinkכדי להבחין ביןEINVALלשגיאות אחרות$!-errnoמוגדר בכישלון;$!{EINVAL}מבדיל בין ״לא symlink״ לשגיאות אחרות