แอพ Mac สามารถติดตามตำแหน่งของไฟล์ได้อย่างไร


18

ฉันสังเกตพฤติกรรมเช่นนี้ใน Mac ของฉัน:

  • เปิด PDF ด้วย PDF Expert ทำการเปลี่ยนแปลงไฟล์ย้ายไฟล์ใน Finder บันทึกใน PDF Expert และมันจะถูกบันทึกอย่างถูกต้องไปยังสถานที่ใหม่
  • เปิดเปลือกในไดเรกทอรีเหมือน~/fooถังขยะไดเรกทอรีที่มี app ~/.Trash/fooอื่นและรหัสผ่านของเปลือกผลได้อย่างถูกต้อง

เกิดอะไรขึ้นภายใต้ประทุน? กรณีเหล่านี้ดูเหมือนจะบ่งบอกว่าแอพไม่ได้มีแค่พา ธ ที่สมบูรณ์ของไฟล์เช่น emacs (ฉันเหมาะสมกับสิ่งนี้หรือไม่) หรือเป็นกลไกที่แตกต่างอย่างสิ้นเชิง?

คำตอบ:


21

macos มี/.vol/ระบบพิเศษที่แมปเข้ากับไดเรกทอรีและไฟล์จริง ไฟล์และไดเรกทอรีสามารถเข้าถึงได้โดย/.vol/<device_id>/<inode_number>ไม่คำนึงถึงว่าไฟล์อยู่ที่ไหนในระบบไฟล์

มันเป็นระบบเล็ก ๆ ที่ดี

ตัวอย่างเช่นโปรแกรมสามารถรับหมายเลขไอโหนด/Users/jdoe/someFile.txtแล้วเปิดผ่าน/.vol/12345/6789(ในกรณีนี้รหัสอุปกรณ์คือ 12345 และหมายเลขไอโหนด 6789) จากนั้นคุณย้ายไป/Users/jdoe/someFile.txtทุกที่ที่คุณต้องการ (ในระดับเสียงเดียวกัน) และทุกอย่างก็ใช้งานได้ คุณสามารถเขียนเชลล์สคริปต์ที่รองรับสิ่งนี้magicได้

ls -di <file> เพื่อรับหมายเลข inode

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

แก้ไข:

คุณใช้statเพื่อรับ id ของไดรฟ์ข้อมูลและหมายเลขไอโหนดตามคำตอบที่เชื่อมโยงตามที่ไฮไลต์โดย IMSoP

GetFileInfo /.vol/12345/6789/Users/jdoe/someFile.txtจะกลับมาที่ตั้งปัจจุบันของแฟ้มอยู่ก่อนหน้านี้ใน

ดู/programming/11951328/is-there-any-function-to-retrieve-the-path-associated-with-an-inodeสำหรับข้อมูลเพิ่มเติม


1
ตามคำตอบที่เชื่อมโยงstatเป็นคำสั่งที่มีประโยชน์มากกว่าที่นี่ls -diเพราะมันจะบอกคุณถึงปริมาณ / หมายเลขอุปกรณ์รวมถึงหมายเลขไฟล์ / หมายเลขไอโหนด
IMSoP

4
ใน Debian ฉันไม่มี/.vol/และสิ่งนี้ยังคงเกิดขึ้น (แม้ว่าฉันต้องการpwd -Pเพียง แต่จากนั้นปรับปรุงผลลัพธ์ของธรรมดาpwd) ฉันเดาว่าโปรแกรมไม่จำเป็นต้องเปิดไฟล์ผ่านเส้นทางพิเศษใด ๆ เพราะโดยทั่วไปแล้วพวกเขาจะได้รับ (และเก็บ) ตัวอธิบายไฟล์ที่แมปไปยัง inodes โดยเคอร์เนลอยู่ดี ฉันสงสัยว่าบน Mac /.vol/นั้นไม่จำเป็นเช่นกัน
Kamil Maciorowski

ดังนั้นหากคุณย้ายไฟล์ไปที่ดิสก์อื่นโครงร่างนี้จะแตก
Joel Coehoorn

1
@JoelCoehoorn ใช่ แต่โดยทางเทคนิคแล้วคุณไม่สามารถย้ายไฟล์ไปยังดิสก์อื่นได้ คุณสามารถคัดลอกไปยังดิสก์อื่นแล้วลบออกและมีทางลัดในการทำเช่นนี้ "หนึ่งขั้นตอน" แต่ก็ยังคงเป็นคัดลอกและลบไม่ใช่การย้ายดังนั้นในทางเทคนิคไฟล์ที่แตกต่างกัน
ibrewster

1
เครื่องมือแก้ไขข้อความจำนวนมากอ่านไฟล์ที่กำหนดปิดทำงานด้วยการคัดลอกและบันทึกไปยังพา ธ เดียวกันดังนั้นพวกเขาจึงสร้างไฟล์ขึ้นในตำแหน่งเดิม แต่พวกเขาอาจทำให้ไฟล์เปิดตลอดเวลาและเขียนมันในตอนท้าย ฉันbashบน Debian ทำเช่นนั้น ฉันเรียกใช้exec 3<>fooแล้วย้ายfooภายในระบบไฟล์เดียวกันecho whatever >&3จากนั้นตรวจสอบfooในตำแหน่งใหม่ - และมันเปลี่ยนไป แม้ว่าbashจะไม่สามารถค้นหาไฟล์ได้ แต่โปรแกรมอื่น ๆ โดยทั่วไปก็สามารถทำได้ ประเด็นของฉัน/.vol/ไม่จำเป็นโปรแกรมสามารถทำงานได้อย่างง่ายดายหากปราศจากมัน หรือฉันไม่เข้าใจสิ่งที่แตกต่าง
Kamil Maciorowski

1

คำตอบด้านล่างนี้เป็นเท็จ (ดูความคิดเห็น) กรุณาเพิกเฉย


นอกเหนือจากคำตอบที่ดีที่ให้มาแล้วมันอาจเป็นไปได้ว่าโปรแกรมของคุณกำลังถือตัวจัดการไฟล์ซึ่งไม่ขึ้นอยู่กับตำแหน่งไฟล์ในแผนผังไดเรกทอรี (และในระบบ Unix ยังคงลบไฟล์อย่างน้อยจนกว่าคุณจะปิดมัน )

การจัดการไฟล์นั้นเป็นการเข้าถึงไฟล์โดยตรงโดยไม่ขึ้นอยู่กับว่าอยู่ที่ไหนหรือบ่อยแค่ไหน (ในกรณีของการเชื่อมโยง) ที่มีอยู่ในโครงสร้างไดเรกทอรี


ไม่คุณไม่ได้รับมันฉันคิดว่า ... ดูความคิดเห็นของฉันที่ @KamilMaciorowski filehandle จะไม่เปลี่ยนแปลงเมื่อคุณบันทึกไฟล์ไฟล์ใหม่จะถูกสร้างขึ้นที่ตำแหน่งเดิม .... ไม่ใช่ใน macos!
thecarpy

1
คุณถูกต้องซึ่งไม่คาดคิดและไม่เหมือนกับยูนิกซ์ :(
ทอม

ตกลงและโหวตขึ้น!
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

การปฏิเสธความรับผิด: ฉันยังไม่ได้ตัดแต่งรายการ "รวม" นี้ถูกแฮ็คเข้าด้วยกันอย่างรวดเร็วเพื่อพิสูจน์จุด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.