Как приложения Mac могут отслеживать местоположение файла?
18
Я наблюдаю такое поведение на моем Mac:
Откройте PDF с PDF Expert, внесите некоторые изменения в файл, переместите файл в Finder, сохраните его в PDF Expert, и он будет правильно сохранен на новом месте.
Откройте оболочку в каталоге, например ~/foo, очистите каталог с другим приложением, и pwd оболочки правильно выведет ~/.Trash/foo.
Что происходит под капотом? Кажется, что эти случаи указывают на то, что приложения не просто хранят абсолютный путь к файлу, как, например, emacs (я прав с этим?), Или это совершенно другой механизм?
У macos есть специальная /.vol/система, сопоставленная с реальным каталогом и файлами. Файлы и каталоги доступны через /.vol/<device_id>/<inode_number>, независимо от того, где файлы находятся в файловой системе.
Это милая маленькая система.
Таким образом, программы могут, например, получить номер инода /Users/jdoe/someFile.txtи затем открыть его через /.vol/12345/6789(в этом случае идентификатор устройства равен 12345, а номер инода 6789). Затем вы перемещаетесь /Users/jdoe/someFile.txtкуда угодно (на ту же громкость), и все просто работает. Вы даже можете написать сценарий оболочки, который поддерживает это magic.
ls -di <file> чтобы получить номер инода.
$ ls -di /User/jdoe/someFile.txt
6789 /User/jdoe/someFile.txt
РЕДАКТИРОВАТЬ:
Вы используете statдля получения идентификатора тома и номера inode, в соответствии со связанным ответом, как выделено IMSoP.
GetFileInfo /.vol/12345/6789вернет текущее местоположение файла, ранее находившегося в /Users/jdoe/someFile.txt.
Согласно связанным ответам, statэто более полезная команда, чем ls -di, поскольку она сообщает вам номер тома / устройства, а также идентификатор файла / номер индекса.
IMSoP
4
В Debian у меня нет, /.vol/и это все еще происходит (хотя мне нужно pwd -P, только тогда pwdобновляется вывод plain ). Я предполагаю, что программы не должны открывать файлы по какому-либо специальному пути, потому что в общем случае они получают (и сохраняют) файловые дескрипторы, которые в любом случае отображаются ядром на inode. Я подозреваю, что на Mac /.vol/это тоже не существенно.
Камиль Мачоровский
Поэтому, если вы переместите файл на другой диск, эта схема нарушится.
Джоэл Коухорн
1
@JoelCoehoorn Да, но технически вы не можете переместить файл на другой диск. Вы можете скопировать его на другой диск, затем удалить его, и есть ярлыки, чтобы сделать это как «один шаг», но это все равно копирование и удаление, а не перемещение, то есть технически другой файл.
ibrewster
1
Многие текстовые редакторы читают данный файл, закрывают его, работают с его копией и сохраняют по тому же пути, поэтому они воссоздают файл в его старом местоположении. Но они могут держать файл открытым все время и писать в него в самом конце. Мой bashна Debian делает это. Я бегу exec 3<>foo, затем переместился fooв ту же файловую систему, echo whatever >&3затем проверил fooновое место - и оно изменилось. Хотя bashне может искать в файле, другие программы в целом могут. Моя точка зрения не /.vol/является существенной, программы могут легко работать без этого. Или я не понимаю, в чем разница.
Камиль Мачоровски
1
Ответ ниже ложный (см. Комментарии). Пожалуйста, игнорируйте
В дополнение к хорошему ответу, который дал Карпи, вполне вероятно, что ваши программы просто держат дескриптор файла , который не зависит от расположения файлов в дереве каталогов (а в системах 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 */constchar*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
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не обрезал список «включить», он был быстро взломан, чтобы доказать свою точку зрения.
stat
это более полезная команда, чемls -di
, поскольку она сообщает вам номер тома / устройства, а также идентификатор файла / номер индекса./.vol/
и это все еще происходит (хотя мне нужноpwd -P
, только тогдаpwd
обновляется вывод plain ). Я предполагаю, что программы не должны открывать файлы по какому-либо специальному пути, потому что в общем случае они получают (и сохраняют) файловые дескрипторы, которые в любом случае отображаются ядром на inode. Я подозреваю, что на Mac/.vol/
это тоже не существенно.bash
на Debian делает это. Я бегуexec 3<>foo
, затем переместилсяfoo
в ту же файловую систему,echo whatever >&3
затем проверилfoo
новое место - и оно изменилось. Хотяbash
не может искать в файле, другие программы в целом могут. Моя точка зрения не/.vol/
является существенной, программы могут легко работать без этого. Или я не понимаю, в чем разница.Ответ ниже ложный (см. Комментарии). Пожалуйста, игнорируйте
В дополнение к хорошему ответу, который дал Карпи, вполне вероятно, что ваши программы просто держат дескриптор файла , который не зависит от расположения файлов в дереве каталогов (а в системах Unix даже не удаляет файл, по крайней мере, пока вы его не закроете) ).
Дескриптор файла - это, по сути, прямой доступ к файлу, независимо от того, где и как часто (в случае жестких ссылок) он существует в структуре каталогов.
источник
Хотя я не уверен, почему macos использует это вместо стандартной функциональности C, предполагая, что то, что я читал много лет назад в «Mac OS X Unleashed», было правильным, оказалось, что я снова узнал что-то новое.
Пожалуйста, посмотрите на следующую простую программу на C:
Скомпилируйте программу, запустите ее в фоновом режиме и быстро
mv file.txt file2.txt
ДО того, как программа напечатает «Законченный сон, запись в файл». (у вас есть 10 секунд)Обратите внимание, что
file2.txt
вывод вашей программы, хотя она была перемещена до того, как текст был напечатан в файл (через дескриптор файла).ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не обрезал список «включить», он был быстро взломан, чтобы доказать свою точку зрения.
источник