Làm thế nào để các ứng dụng Mac có thể theo dõi vị trí của tệp?


18

Tôi quan sát hành vi như thế này trên máy Mac của mình:

  • Mở tệp PDF với PDF Expert, thực hiện một số thay đổi đối với tệp, di chuyển tệp trong Finder, lưu tệp đó trong PDF Expert và nó sẽ được lưu chính xác vào vị trí mới.
  • Mở một shell trong một thư mục như ~/foo, dọn rác thư mục với một ứng dụng khác và pwd của shell sẽ xuất ra chính xác ~/.Trash/foo.

Chuyện gì đang xảy ra dưới mui xe? Những trường hợp này dường như cho thấy các ứng dụng không chỉ giữ một đường dẫn tuyệt đối của tệp như emacs (tôi có đúng với điều này không?), Hay đó là một cơ chế hoàn toàn khác?

Câu trả lời:


21

macos có một /.vol/hệ thống đặc biệt được ánh xạ tới thư mục và tệp thực tế. Các tệp và thư mục có thể truy cập thông qua /.vol/<device_id>/<inode_number>, bất kể các tệp nằm ở đâu trên hệ thống tệp.

Đó là một hệ thống nhỏ đẹp.

Vì vậy, các chương trình có thể lấy số inode của /Users/jdoe/someFile.txtvà sau đó mở nó qua /.vol/12345/6789(trong trường hợp này, id thiết bị là 12345 và số inode 6789). Sau đó, bạn di chuyển /Users/jdoe/someFile.txtbất cứ nơi nào bạn muốn (trên cùng một âm lượng) và mọi thứ chỉ hoạt động. Bạn thậm chí có thể viết một kịch bản shell hỗ trợ này magic.

ls -di <file> để có được số inode.

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

CHỈNH SỬA:

Bạn sử dụng statđể lấy id của âm lượng và số inode, theo câu trả lời được liên kết như được đánh dấu bởi IMSoP.

GetFileInfo /.vol/12345/6789sẽ trả về vị trí hiện tại của tệp được đặt trước đó /Users/jdoe/someFile.txt.

Xem /programming/11951328/is-there-any-feft-to-retrieve-the-path-associated-with-an-inode để biết thêm thông tin.


1
Theo các câu trả lời được liên kết, đây statlà một lệnh hữu ích hơn ls -divì nó cho bạn biết ID âm lượng / thiết bị cũng như ID tệp / số inode.
IMSoP

4
Trong Debian tôi không có /.vol/và điều này vẫn xảy ra (mặc dù tôi cần pwd -P, chỉ sau đó đầu ra của đồng bằng pwdđược cập nhật). Tôi đoán các chương trình không phải mở tệp thông qua bất kỳ đường dẫn đặc biệt nào vì nói chung, chúng nhận được (và giữ) các mô tả tệp được ánh xạ tới các hạt nhân bằng cách nào. Tôi nghi ngờ trên Mac /.vol/là không cần thiết là tốt.
Kamil Maciorowski

Vì vậy, nếu bạn di chuyển một tệp sang một đĩa khác, lược đồ này bị hỏng.
Joel Coehoorn

1
@JoelCoehoorn Có, nhưng về mặt kỹ thuật, bạn không thể di chuyển tệp sang đĩa khác. Bạn có thể sao chép nó sang đĩa khác, sau đó xóa nó và có các phím tắt để thực hiện điều này dưới dạng "một bước", nhưng nó vẫn là một bản sao và xóa, không phải là một động thái, vì vậy, về mặt kỹ thuật là một tệp khác.
ibrewster

1
Nhiều trình soạn thảo văn bản đọc một tệp đã cho, đóng tệp, làm việc với bản sao của tệp đó và lưu vào cùng một đường dẫn để họ tạo lại tệp ở vị trí cũ. Nhưng họ có thể giữ tập tin mở mọi lúc và ghi vào cuối. My bashtrên Debian làm điều đó. Tôi chạy exec 3<>foo, sau đó di chuyển footrong cùng một hệ thống tập tin echo whatever >&3, sau đó kiểm tra foovị trí mới - và nó đã thay đổi. Mặc dù bashkhông thể tìm kiếm trong tập tin, các chương trình khác nói chung có thể. Quan điểm của tôi /.vol/là không cần thiết, các chương trình có thể dễ dàng hoạt động như thế này mà không cần nó. Hoặc tôi không nhận được sự khác biệt là gì.
Kamil Maciorowski

1

Câu trả lời dưới đây là sai (xem bình luận). Làm ơn bỏ qua


Ngoài câu trả lời hay mà thecarpy đã đưa ra, có khả năng các chương trình của bạn chỉ đơn giản là xử lý tệp , độc lập với vị trí tệp trong cây thư mục (và trên các hệ thống Unix thậm chí còn duy trì xóa tệp, ít nhất là cho đến khi bạn đóng nó ).

Một xử lý tệp về cơ bản là truy cập trực tiếp vào tệp, độc lập với vị trí hoặc tần suất (trong trường hợp liên kết cứng) nó tồn tại trong cấu trúc thư mục.


Không, bạn cũng không hiểu, tôi nghĩ ... hãy xem bình luận của tôi cho @KamilMaciorowski. Filehandle không thay đổi, khi bạn lưu tệp, một tệp mới được tạo tại vị trí ban đầu .... không như vậy trên macos!
thecarpy

1
Bạn đúng, điều đó rất bất ngờ và không giống như Unix. :(
Tom

Đồng ý và nâng cao!
thecarpy

0

Mặc dù tôi không chắc tại sao macos sử dụng chức năng này thay vì chức năng C tiêu chuẩn, giả sử những gì tôi đọc cách đây nhiều năm trong "Mac OS X Unleashed" là chính xác, nhưng hóa ra tôi lại học được một điều mới.

Vui lòng xem chương trình C đơn giản sau:

#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);
}

Biên dịch chương trình, chạy nó trong nền và nhanh chóng mv file.txt file2.txtTRƯỚC KHI chương trình in "Ngủ xong, ghi vào tệp." (bạn có 10 giây)

Lưu ý rằng file2.txtcó đầu ra của chương trình của bạn mặc dù nó đã được di chuyển trước khi văn bản được in ra tệp (thông qua mô tả tệp).

$ 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

TUYÊN BỐ TỪ CHỐI: Tôi chưa cắt xén danh sách "bao gồm", điều này đã nhanh chóng được hack cùng nhau để chứng minh một quan điểm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.