stat#
מקבל את מידע הסטטוס של קובץ.
stat מבקש ממערכת ההפעלה את רשומת המטא־נתונים של קובץ - גודל, בעלות, הרשאות, חותמות זמן, inode - ומחזיר אותה כרשימה בת 13 איברים. זוהי הפרימיטיב הבסיסי שמאחורי בדיקות הקבצים -X (-e, -f, -r, …), מאחורי מודולים כמו File::stat, ומאחורי כל סקריפט שצריך לבדוק קובץ מבלי לפתוח אותו. stat מבטל הפניות של symlinks ומדווח על היעד; יש להשתמש ב־lstat כדי לקבל את הקישור עצמו.
תקציר#
stat FILEHANDLE
stat EXPR
stat DIRHANDLE
stat
stat _
מה מקבלים בחזרה#
בהקשר רשימה, רשימה בת 13 איברים של שדות מספריים. בהקשר סקלר, בוליאני: אמת בהצלחה, שקר בכשל. בכל מקרה, בהצלחה ה־buffer של stat של הקרנל נשמר ב־cache במטפל הקובץ המיוחד _, ש־stat, lstat, או בדיקת -X עוקבים יכולים להשתמש בו מחדש ללא syscall חדש.
בכשל, הקשר רשימה מחזיר את הרשימה הריקה ו־$! מוגדר לערך errno מ־stat(2) שנכשל.
השדות, לפי הסדר:
אינדקס | שדה | משמעות |
|---|---|---|
0 |
| מספר ההתקן של מערכת הקבצים המחזיקה את הקובץ |
1 |
| מספר inode |
2 |
| מצב קובץ - ביטי סוג וגם ביטי הרשאה משולבים |
3 |
| מספר הקישורים הקשיחים לקובץ |
4 |
| מזהה משתמש מספרי של הבעלים |
5 |
| מזהה קבוצה מספרי של הבעלים |
6 |
| מזהה התקן, עבור קבצים מיוחדים של תווים/בלוקים |
7 |
| גודל כולל בבייטים |
8 |
| זמן הגישה האחרונה, שניות מאז ה־epoch (1970-01-01 00:00 GMT) |
9 |
| זמן השינוי האחרון, שניות מאז ה־epoch |
10 |
| זמן שינוי inode, שניות מאז ה־epoch - לא זמן יצירה |
11 |
| גודל בלוק קלט/פלט מועדף לקריאות/כתיבות כנגד הקובץ הזה |
12 |
| מספר בלוקי מערכת הקבצים שהוקצו בפועל (לרוב 512 בייטים כל אחד) |
שדה 2 (mode) אורז גם את סוג הקובץ וגם את ביטי ההרשאה במספר אחד. יש למסך עם 07777 כדי לראות רק את ההרשאות; יש להשתמש בקבועי S_IF* ובמסייעי S_IS* מ־Fcntl כדי לבדוק את הסוג בצורה נישאת.
my $mode = (stat($filename))[2];
printf "permissions are %04o\n", $mode & 07777;
לא כל מערכת קבצים מאכלסת כל שדה. atime, blksize, ו־blocks עשויים לחזור כ־0 במערכות קבצים שאינן עוקבות אחריהם (לדוגמה כמה mounts של FUSE או מערכות קבצים רשת); ctime אינו ”זמן יצירה“ נישא - הוא עוקב אחר השינוי האחרון של ה־inode עצמו (הרשאות, בעלות, ספירת קישורים), לא מתי הקובץ נוצר לראשונה.
מצב גלובלי שהוא נוגע בו#
$_- נקרא כאשרstatנקרא ללא ארגומנט.statללאEXPRמבצע stat על שם הקובץ המוחזק ב־$_, לא על מטפל ה־_ב־cache.$!- מוגדר ל־errnoשל ה־stat(2)syscall שנכשל כאשר הקריאה נכשלת.מטפל הקובץ המיוחד
_- cache לכל מפרש של תוצאתstat,lstat, או-Xמוצלחת אחרונה. העברת_כארגומנט עושה שימוש חוזר ב־buffer ה־cached הזה ואינה מנפיקה syscall. קריאות מוצלחות מרעננות אותו; קריאות שנכשלו משאירות את התוכן הקודם במקום.
דוגמאות#
פירוק בסיסי בהקשר רשימה:
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
$atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);
בחירת שדה יחיד עם פרוסת רשימה:
my $size = (stat($filename))[7];
my $mtime = (stat($filename))[9];
הקשר סקלר כבדיקת קיום־ועוד־מטא־נתונים־קריאים:
if (stat($path)) {
my $size = (stat _)[7]; # reuse the cached buffer
print "size = $size\n";
} else {
warn "stat $path: $!";
}
שימוש חוזר ב־cache לרוחב בדיקת -X ו־stat:
if (-x $file && (($d) = stat(_)) && $d < 0) {
print "$file is executable NFS file\n";
}
גישה במאחזרים בעלי שם דרך File::stat:
use File::stat;
my $sb = stat($filename);
printf "file %s, size %s, perm %04o, mtime %s\n",
$filename, $sb->size, $sb->mode & 07777,
scalar localtime $sb->mtime;
פענוח ה־mode עם Fcntl:
use Fcntl ':mode';
my $mode = (stat($filename))[2];
printf "permissions %04o\n", S_IMODE($mode);
print "is a directory\n" if S_ISDIR($mode);
מקרי קצה#
ללא ארגומנט:
stat;מבצע stat על$_, לא על מטפל ה־_ב־cache. כדי לקרוא מחדש את ה־cache יש לכתובstat(_)כשהקו התחתון הוא bareword מפורש.ה־bareword
_הוא מיוחד: הוא מציין את ה־cache של stat, לא קובץ. ציטוט שלו (stat("_")) מבצע stat על קובץ הנקרא מילולית_בספרייה הנוכחית.Symlinks נעקבים:
statמדווח על היעד של symlink. עבור הקישור עצמו, יש להשתמש ב־lstat. symlink שבור גורם ל־statלהיכשל עםENOENT;lstatעל אותו נתיב מצליח.צורת DIRHANDLE: העברת מטפל ספרייה מ־
opendirמחזירה את ה־stat של הספרייה הפתוחה עצמה. לא כל פלטפורמה תומכת בזה; באלה שלא, הקריאה נכשלת ו־$!מוגדר.מספרי inode עלולים לגלוש ממספרים שלמים: במערכות קבצים עם מספרי inode בני 64 ביט מעבר לטווח המספרים השלמים של Perl,
inoמוחזר כמחרוזת עשרונית כדי לשמר את הערך המלא. יש להשוות מספרי inode עםeq, לא==, כדי להישאר נכונים על מערכות הקבצים האלה.eqעובד בסדר גם על inodes מספריים.ctimeאינו זמן יצירה: זהו זמן שינוי ה־inode - מעודכן על ידיchmod,chown,rename, שינויי ספירת קישורים, וכתיבות הקובץ עצמן. Linux חושף זמן יצירה אמיתי (btime) דרךstatx(2), אך זה אינו חלק מרשימת ההחזרה שלstat.שדות אפס במערכות קבצים מסוימות:
atime(ב־mounts שלnoatime),blksize, ו־blocksעלולים להיות מדווחים כ־0. יש להתייחס ל־0כ“לא זמין“, לא כערך משמעותי.הקשר סקלר אינו מאכלס את
_בכשל:statשנכשל משאיר את ה־buffer ה־cached הקודם ללא נגיעה. תמיד יש לבדוק את ערך ההחזרה לפניstat(_)או-X _המשך.חלונות race: המטא־נתונים המוחזרים הם תצלום מצב. כל דבר הפועל על נתיב על סמך תוצאת
stat(בדיקות הרשאה, דפוסי TOCTOU) חייב להיכתב לסבול שינוי הקובץ בין ה־statלפעולת ההמשך - או יותר טוב, לפתוח את הקובץ תחילה ולבצעstatעל מטפל הקובץ.
הבדלים מהמקור#
תואם במלואו ל־Perl 5.42 במקור.
ראו גם#
lstat- כמוstatאך אינו עוקב אחר symlinks; מדווח על הקישור עצמואופרטורי בדיקת קובץ
-X(-e,-f,-r,-w,-x, …) - בנויים מעל אותו buffer של stat; חולקים את ה־cache_עםstatו־lstatchmod- משנה את ביטי ההרשאה המדווחים בשדה 2 (mode)chown- משנה את ה־uidוה־gidהמדווחים בשדות 4 ו־5File::stat- מאחזרים בעלי שם ($sb->size,$sb->mtime, …) מעל אותה רשימה בת 13 שדות;use File::statדורס אתstatבתיחום הנוכחיFcntl- התג:modeמייצא את קבועיS_I*ומסייעיS_IS*לפענוח שדה 2