Як програми Mac можуть відстежувати місцезнаходження файлу?


18

Я спостерігаю таку поведінку на моєму Mac:

  • Відкрийте PDF з PDF Expert, внесіть деякі зміни до файлу, перемістіть файл у Finder, збережіть його у PDF Expert і він буде правильно збережений на новому місці.
  • Відкрийте оболонку в каталозі, як-от ~/foo, перейдіть в каталог з іншим додатком і pwd оболонки правильно виведе ~/.Trash/foo.

Що відбувається під кришкою? Ці випадки, схоже, вказують на те, що програми не просто містять абсолютний шлях до файлу, як-от emacs (я прав? З цим?), Або це зовсім інший механізм?

Відповіді:


21

macos має спеціальну /.vol/систему, відображену у фактичному каталозі та файлах. До файлів і каталогів можна отримати доступ /.vol/<device_id>/<inode_number>незалежно від місця, де вони знаходяться у файловій системі.

Це приємна маленька система.

Таким чином, програми можуть, наприклад, отримати номер inode, /Users/jdoe/someFile.txtа потім відкрити його /.vol/12345/6789(у цьому випадку ідентифікатор пристрою - 12345, а номер inode 6789). Потім ви рухаєтесь /Users/jdoe/someFile.txtкуди завгодно (на однаковий обсяг), і все просто працює. Ви навіть можете написати скрипт оболонки, який це підтримує magic.

ls -di <file> щоб отримати номер inode.

$ ls -di /User/jdoe/someFile.txt
6789 /User/jdoe/someFile.txt

Редагувати:

Ви використовуєте statдля отримання ідентифікатора гучності та номера inode відповідно до пов'язаної відповіді, яку підкреслив IMSoP.

GetFileInfo /.vol/12345/6789поверне поточне розташування файлу, який раніше знаходився в /Users/jdoe/someFile.txt.

Для отримання додаткової інформації див. Https://stackoverflow.com/questions/11951328/is-there-any-function-to-retrieve-the-path-associated-with-an-inode .


1
Відповідно до пов'язаних відповідей, statтут є більш корисною командою, ніж ls -di, оскільки вона повідомляє вам об'єм / ідентифікатор пристрою, а також ідентифікатор файла / номер вводу.
IMSoP

4
У Debian у мене немає, /.vol/і це все одно відбувається (хоча мені це потрібно pwd -P, тільки тоді вихід звичайної інформації pwdоновлюється). Я думаю, що програмам не потрібно відкривати файли будь-яким спеціальним контуром, оскільки вони, як правило, отримують (і зберігають) дескриптори файлів, які ядро ​​так чи інакше відображаються в inode. Я підозрюю, що на Mac /.vol/також не важливо.
Каміль Маціоровський

Отже, якщо ви перемістите файл на інший диск, ця схема порушується.
Joel Coehoorn

1
@JoelCoehoorn Так, але технічно ви не можете перемістити файл на інший диск. Ви можете скопіювати його на інший диск, потім видалити, і є ярлики, щоб зробити це як "один крок", але це все-таки копіювання та видалення, а не переміщення, технічно інший файл.
ibrewster

1
Багато текстових редакторів читають заданий файл, закривають його, працюють з його копією та зберігають на тому самому шляху, щоб вони відтворили файл у його старому місці. Але вони можуть постійно тримати файл відкритим і записувати в нього в самому кінці. Мій bashна Debian це робить. Я запускаю exec 3<>foo, потім переміщуюсь fooв одній файловій системі, echo whatever >&3потім перевіряю fooв новому місці - і це змінюється. Хоча bashне можна шукати всередині файлу, інші програми взагалі можуть. Моя думка не /.vol/є суттєвою, програми можуть легко працювати так, як без цього. Або я не розумію, в чому різниця.
Каміль Маціоровський

1

Відповідь нижче хибна (див. Коментарі). Будь ласка, ігноруйте


Окрім хорошої відповіді, яку дав the carpy, ймовірно, що ваші програми просто тримають ручку файлу , яка не залежить від розташування файлів у дереві каталогів (а в системах Unix навіть зберігається видалення файлу, принаймні, поки ви не закриєте його ).

Обробка файлу - це, по суті, прямий доступ до файлу, незалежно від того, де і як часто (у випадку жорстких посилань) він існує в структурі каталогу.


Ні, у вас це теж не вийшло, я думаю ... дивіться мій коментар до @KamilMaciorowski. Файл файлів не змінюється, коли ви зберігаєте файл, створюється новий файл у вихідному місці .... не так, як у macos!
thecarpy

1
Ви праві, це дуже несподівано і дуже не схоже на Unix. :(
Том

Домовились і схвалили!
thecarpy

0

Хоча я не впевнений, чому macos використовує це замість стандартної функціональності C, припускаючи, що те, що я читав роки тому в "Mac OS X Unleashed", є правильним, але, виявляється, я знову дізнався щось нове.

Будь ласка, подивіться на таку просту програму C:

#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    struct timespec ts;
        ts.tv_sec = 10;
        ts.tv_nsec = 0;
    FILE * fp;

    fp = fopen("file.txt", "a");
    int f = fileno(fp);

    if (fp == NULL)
    {
        printf("Error opening file!\n");
        exit(1);
    }

    struct stat file_stat;
    int ret;
    ret = fstat (f, &file_stat);
    printf("inode number is %d\n", file_stat.st_ino);
    nanosleep(&ts, NULL);

    printf("Finished sleep, writing to file.\n");

/* print some text */
    const char *text = "Write this to the file";
    dprintf(f, "Some text: %s\n", text);

/* print integers and floats */
    int i = 1;
    float py = 3.1415927;
    dprintf(f, "Integer: %d, float: %f\n", i, py);

/* printing single characters */
    char c = 'A';
    dprintf(f, "A character: %c\n", c);

    close(f);
}

Складіть програму, запустіть її у фоновому режимі та швидко mv file.txt file2.txtПЕРЕД ПРО програмою надрукується "Готовий сон, написання у файл". (у вас є 10 секунд)

Зверніть увагу, що file2.txtмає вихід вашої програми, хоча вона була переміщена до друку тексту до файлу (через дескриптор файлу).

$ gcc myfile.c
$ ./a.out &
[1] 21416
$ inode number is 83956
$ ./mv file.txt file2.txt
$ Finished sleep, writing to file.
[1]+  Done                    ./a.out
$ cat file2.txt
Some text: Write this to the file
Integer: 1, float: 3.141593
A character: A

ВІДМОВА: Я не перерізав список "включити", це було швидко зламано разом, щоб довести свою точку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.