chdir#
משנה את ספריית העבודה הנוכחית של התהליך.
chdir הוא העטיפה של Perl סביב קריאות המערכת chdir(2) ו־ - היכן שהקרנל תומך בכך - fchdir(2). הוא משנה את הספרייה שכנגדה נתיבים יחסיים מקבלים פתרון עבור התהליך הנוכחי, ובהצלחה משמר את השינוי הזה לכל פעולת קובץ עוקבת בתוכנית.
תקציר#
chdir EXPR
chdir FILEHANDLE
chdir DIRHANDLE
chdir
מה מקבלים בחזרה#
1 בהצלחה, 0 בכישלון. בכישלון $! נקבע ל־errno הבסיסי כדי שניתן יהיה להבדיל בין ״אין ספרייה כזו״ (ENOENT), ״הרשאה נדחתה״ (EACCES), לבין ״לא ספרייה״ (ENOTDIR):
chdir $path
or die "chdir $path failed: $!";
ההחזרה היא תמיד בוליאני פשוט - אין ערך נפרד של ״הוחלף לשום מקום כי לא ניתן ארגומנט״. הצורה ללא־ארגומנט מצליחה או על־ידי החלפה לספריית הבית או נכשלת כמו כל קריאה אחרת.
מצב גלובלי שהוא נוגע בו#
%ENV- נקרא כאשרchdirנקרא ללא ארגומנט. סדר החיפוש הוא$ENV{HOME}תחילה, אחר־כך$ENV{LOGDIR}. אם אף אחד מהם לא מוגדר,chdirלא עושה דבר ומחזיר0.$!- נקבע בכישלון ל־errnoשדווח על־ידי הקרנל.
chdir אינו מעדכן את $ENV{PWD}. מעטפות (shells) מתחזקות את PWD בעצמן; תוכנית Perl שאכפת לה מ־PWD עבור תהליכי־ילד צריכה להציב ל־$ENV{PWD} לאחר chdir מוצלח.
צורות ארגומנט#
chdir EXPR-EXPRמומר למחרוזת ומועבר ל־chdir(2)כשם נתיב. נתיבים יחסיים מקבלים פתרון כנגד ספריית העבודה הנוכחית ברגע הקריאה.chdir FILEHANDLEו־chdir DIRHANDLE- בלינוקס (וכל מערכת עםfchdir(2)) הקרנל משנה ספרייה לזו שאליה המטפל מתייחס.FILEHANDLEכאן משמעו מטפל קובץ שנפתח על ספרייה, או מטפל ספרייה מ־opendir. שימוש בצורת המטפל נמנע ממירוץ TOCTOU בין פתרון שם נתיב לבין החלפה אליו.chdir(ללא ארגומנט) - מחליף ל־$ENV{HOME}, ונופל חזרה ל־$ENV{LOGDIR}אםHOMEלא מוגדר. אם שניהם לא מוגדרים הקריאה נכשלת ו־$!נשאר ללא שינוי; יש לבדוק את ערך ההחזרה, לא את$!.
דוגמאות#
החלפה לספרייה ויציאה אם היא לא קיימת:
chdir "/var/log"
or die "cannot enter /var/log: $!";
הרצת בלוק עבודה בספרייה אחרת וחזרה למקום בו התחלתם:
use Cwd qw(getcwd);
my $origin = getcwd;
chdir $work_dir or die "chdir $work_dir: $!";
# ... do work relative to $work_dir ...
chdir $origin or die "chdir $origin: $!";
החלפה דרך מטפל ספרייה (ללא תנאי־מירוץ במערכות עם fchdir(2)):
opendir my $dh, $path or die "opendir $path: $!";
chdir $dh or die "fchdir $path: $!";
לחזור הביתה:
chdir or die "no HOME/LOGDIR in environment";
בדיקה של רשימת מועמדים, עצירה בראשון שעובד:
for my $d ("/srv/app", "/opt/app", "/usr/local/app") {
last if chdir $d;
}
מקרי קצה#
Empty string or
undef:chdir ""andchdir undefboth fail and set$!toENOENT. They do not fall back to$HOMEthe no-argument form is triggered by absence of an argument, not by an argument that happens to be empty.
נתיבים יחסיים ב־thread עם cwd משלו: ספריית העבודה הנוכחית של הקרנל היא לכל־תהליך, לא לכל־thread, בלינוקס. שני thread-ים הקוראים ל־
chdirבו־זמנית מתחרים.symlink לספרייה:
chdirעוקב אחרי symlink-ים, ונוחת ביעד. יש להשתמש ב־readlinkאוCwd::abs_pathקודם אם צריך לדעת את היעד האמיתי.ספרייה שנמחקה: אם הספרייה הוסרה לאחר שנכנסתם אליה, פעולות יחסיות מבפנים נכשלות עם
ENOENTורוב המעטפות מציגות את הנתיב כ־(deleted). עדיין ניתן לבצעchdirהחוצה בעזרת נתיב מוחלט.צורת המטפל במערכות ללא
fchdir(2): מעלה חריגה. לינוקס תמיד תומך בכך; ההגבלה היא דאגת ניידות עבור קוד שרץ גם על מערכות ישנות יותר.קלט לא־מהימן: העברת נתיב שסופק על־ידי משתמש ל־
chdirללא ולידציה מאפשרת לקורא להפנות מחדש את כל פעולות הנתיב היחסי הבאות בתוכנית. יש לקנן (canonicalise) באמצעותCwd::abs_pathולבדוק כנגד allow-list לפני הקריאה אם הקלט חוצה גבול אמון.לאחר
fork: הילד יורש את ה־cwd של ההורה.chdirבילד אינו משפיע על ההורה.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
mkdir- יצירת ספרייה; מצמדים עםchdirכשבונים סביבת עבודה ונכנסים אליהrmdir- מחיקת ספרייה; לא לבצעrmdirעל ה־cwd, יש לבצעchdirהחוצה תחילהopendir- פתיחת מטפל ספרייה שניתן להשתמש בו כארגומנט ל־chdirעבור שינויי ספרייה נטולי תנאי־מירוץchroot- בידוד חזק יותר מ־chdir; משנה את שורש מערכת הקבצים עבור התהליך, לא רק את ה־cwd$ENV{HOME}- מתייעצים בו על־ידי צורת ללא־הארגומנט שלchdirלפני נפילה חזרה ל־$ENV{LOGDIR}$!- נושא את ה־errnoכאשרchdirמחזיר0