Mac 앱은 파일 위치를 어떻게 추적 할 수 있습니까?


18

Mac에서 다음과 같은 동작이 관찰됩니다.

  • PDF Expert로 PDF를 열고 파일을 일부 변경 한 후 Finder에서 파일을 이동하고 PDF Expert에 저장하면 새 위치에 올바르게 저장됩니다.
  • 같은 디렉토리에서 쉘을 열고 ~/foo다른 응용 프로그램으로 디렉토리를 휴지통으로 옮기면 쉘의 pwd가 올바르게 출력 ~/.Trash/foo됩니다.

후드 아래에서 무슨 일이 일어나고 있습니까? 이 사례는 앱이 emacs와 같은 파일의 절대 경로를 보유하지 않는다는 것을 나타내는 것 같습니다 (나에게 맞습니까?). 또는 완전히 다른 메커니즘입니까?

답변:


21

macos에는 /.vol/실제 디렉토리와 파일에 매핑 된 특수 시스템이 있습니다. 파일과 /.vol/<device_id>/<inode_number>파일은 파일 시스템의 파일 위치에 관계 없이을 통해 액세스 할 수 있습니다.

멋진 작은 시스템입니다.

따라서 프로그램은 예를 들어 inode 번호를 얻은 /Users/jdoe/someFile.txt다음이를 통해 열 수 있습니다 /.vol/12345/6789(이 경우 장치 ID는 12345이고 inode 번호 6789). 그런 다음 /Users/jdoe/someFile.txt원하는 곳으로 (같은 볼륨으로) 움직이면 모든 것이 작동합니다. 이것을 지원하는 쉘 스크립트를 작성할 수도 있습니다 magic.

ls -di <file> 아이 노드 번호를 얻으려면.

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

편집하다:

statIMSoP가 강조 표시 한 링크 된 답변에 따라 볼륨 및 아이 노드 번호의 ID를 가져 오는 데 사용 합니다.

GetFileInfo /.vol/12345/6789이전에 위치한 파일의 현재 위치를 반환합니다 /Users/jdoe/someFile.txt.

자세한 내용은 /programming/11951328/is-there-any-function-to-retrieve-the-path-with-an-inode 를 참조하십시오.


1
링크 된 답변에 따르면 볼륨 / 장치 ID와 파일 ID / 아이 노드 번호를 알려주기 때문에 stat여기보다 더 유용한 명령 ls -di입니다.
IMSoP

4
데비안에서는 나는 이것을 가지고 있지 않으며 /.vol/여전히 발생합니다 (필요하지만 pwd -P평범한 출력 만 pwd업데이트됩니다). 프로그램은 특별한 경로를 통해 파일을 열 필요가 없다고 생각합니다. 일반적으로 커널에 의해 inode에 매핑되는 파일 디스크립터를 얻거나 유지하기 때문입니다. 나는 Mac 에서도 중요하지 않다고 생각/.vol/ 합니다.
Kamil Maciorowski

따라서 파일을 다른 디스크로 이동하면이 체계가 중단됩니다.
Joel Coehoorn

1
@JoelCoehoorn 예. 기술적 으로 파일을 다른 디스크 로 이동할 수는 없습니다 . 다른 디스크에 복사 한 다음 삭제할 수 있으며이를 "한 단계"로 수행 할 수있는 바로 가기가 있지만 여전히 이동 및 복사가 아니라 기술적으로 다른 파일입니다.
ibrewster

1
많은 텍스트 편집기는 주어진 파일을 읽고 닫고 복사본을 사용하여 동일한 경로에 저장하여 이전 위치에서 파일을 다시 만듭니다. 그러나 그들은 파일을 항상 열어두고 맨 끝에 쓸 수 있습니다. 나의 bash데비안은 그렇게한다. 을 실행 exec 3<>foo한 다음 foo동일한 파일 시스템 내에서 이동 echo whatever >&3한 다음 foo새 위치 를 확인 했습니다. 변경되었습니다. 하지만이 bash파일 내에서 일반 캔에서 다른 프로그램을 추구 할 수 없다. 내 요점은 /.vol/필수는 아니며 프로그램이 없으면 쉽게 작동 할 수 있습니다. 또는 차이점이 무엇인지 알 수 없습니다.
Kamil Maciorowski

1

아래 답변은 허위입니다 (의견 참조). 무시하세요


thecarpy가 제공 한 좋은 대답 외에도 프로그램은 단순히 디렉토리 트리의 파일 위치와 독립적 인 파일 핸들을 잡고있을 가능성이 높습니다 (그리고 Unix 시스템에서는 적어도 닫을 때까지 파일 삭제를 유지합니다) ).

파일 핸들은 기본적으로 디렉토리 구조에서 파일의 위치 또는 빈도 (하드 링크의 경우)에 관계없이 파일에 직접 액세스하는 것입니다.


아니, 당신도 그것을 얻지 못했다고 생각합니다 ... @KamilMaciorowski에 대한 내 의견을 참조하십시오. 파일 핸들은 변경되지 않으며, 파일을 저장할 때 원래 위치에 새 파일이 생성됩니다 .... macOS에서는 그렇지 않습니다!
thecarpy

1
유닉스와는 달리 예상치 못한 매우 정확합니다. :(
Tom

합의와 공감!
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.