Mac uygulamaları bir dosyanın konumunu nasıl izleyebilir?


18

Mac bilgisayarımda böyle bir davranış gözlemliyorum:

  • PDF Uzmanı ile bir PDF açın, dosyada bazı değişiklikler yapın, dosyayı Finder'a taşıyın, PDF Uzmanı'na kaydedin ve doğru bir şekilde yeni yere kaydedilecektir.
  • Gibi bir dizinde bir kabuk açın ~/foo, dizini başka bir uygulama ile çöp kutusuna atın ve kabuğun pwd doğru çıktılar ~/.Trash/foo.

Kaputun altında neler oluyor? Bu durumlar, uygulamaların sadece emacs gibi dosyanın mutlak bir yolunu tutmadıklarını gösteriyor (bu konuda haklı mıyım?) Yoksa tamamen farklı bir mekanizma mı?

Yanıtlar:


21

macos, /.vol/gerçek dizine ve dosyalara eşlenmiş özel bir sisteme sahiptir . Dosyalara ve dizinlere /.vol/<device_id>/<inode_number>, dosyaların dosya sisteminde nerede olduğuna bakılmaksızın erişilebilir .

Güzel, küçük bir sistem.

Böylece, programlar örneğin inode numarasını alabilir /Users/jdoe/someFile.txtve daha sonra üzerinden açabilir /.vol/12345/6789(bu durumda cihaz kimliği 12345 ve inode numarası 6789). Daha sonra /Users/jdoe/someFile.txtistediğiniz yere taşıyın (aynı hacimde) ve her şey işe yarıyor. Bunu destekleyen bir kabuk betiği bile yazabilirsiniz magic.

ls -di <file> inode numarası almak için.

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

DÜZENLE:

statIMSoP tarafından vurgulanan bağlı cevaba göre birim ve inode numarasının kimliğini almak için kullanılır .

GetFileInfo /.vol/12345/6789, daha önce içinde bulunan dosyanın geçerli konumunu döndürür /Users/jdoe/someFile.txt.

Daha fazla bilgi için, bkz. Https://stackoverflow.com/questions/11951328/is-there-any-function-to-retrieve-the-path-associated-with-an-inode .


1
Bağlantılı cevaplara göre, statburada ls -dibirim / cihaz kimliğinin yanı sıra dosya kimliği / inode numarasını da söylediğinden daha yararlı bir komuttur .
IMSoP

4
Debian'da hiç yok /.vol/ve bu hala oluyor (ihtiyacım olmasına rağmen pwd -P, ancak o zaman ovanın çıktısı pwdgüncelleniyor). Programların dosyaları herhangi bir özel yolla açması gerekmez, çünkü genel olarak çekirdek tarafından zaten düğümlere eşlenen dosya tanımlayıcıları alırlar (ve saklarlar). Ben şüpheli Mac'te /.vol/de gerekli değildir.
Kamil Maciorowski

Bir dosyayı farklı bir diske taşırsanız, bu şema kırılır.
Joel Coehoorn

1
@JoelCoehoorn Evet, ancak teknik olarak dosyayı farklı bir diske taşıyamazsınız . Diğer diske kopyalayabilir ve silebilirsiniz ve bunu "tek adım" olarak yapmak için kısayollar vardır, ancak yine de bir kopya değil silme işlemidir, bu nedenle teknik olarak farklı bir dosyadır.
ibrewster

1
Birçok metin düzenleyicisi belirli bir dosyayı okur, kapatır, kopyayla çalışır ve aynı yola kaydeder, böylece dosyayı eski konumunda yeniden oluştururlar. Ancak dosyayı her zaman açık tutabilir ve sonunda yazabilirler. bashDebian benim bunu yapar. Çalıştırdım exec 3<>foo, sonra fooaynı dosya sistemine taşındım echo whatever >&3, sonra fooyeni konumu kontrol ettim - ve değişti. Her ne kadar bash, dosya içinde genel tenekede diğer programları peşinde olamaz. Demek istediğim /.vol/önemli değil, programlar onsuz bu şekilde kolayca çalışabilir. Ya da farkın ne olduğunu anlamıyorum.
Kamil Maciorowski

1

Aşağıdaki cevap yanlıştır (yorumlara bakınız). Lütfen dikkate almayın


Thecarpy'ın verdiği iyi yanıta ek olarak, programlarınızın dizin ağacındaki dosya konumundan bağımsız bir dosya tanıtıcısı tutması muhtemeldir (ve Unix sistemlerinde en azından siz kapatana kadar dosya silmeye devam eder) ).

Bir dosya tanıtıcısı, temel olarak dosyaya, dizin yapısında nerede veya ne sıklıkta (sabit bağlantı olması durumunda) doğrudan erişimdir.


Hayır, sen de anlamadın, sanırım ... @KamilMaciorowski hakkındaki yorumuma bakın. Dosya tanıtıcısı değişmez, daha sonra dosyayı kaydettiğinizde, orijinal konumda yeni bir dosya oluşturulur .... macos'ta öyle değil!
thecarpy

1
Haklısın, bu çok beklenmedik ve Unix'ten çok farklı. :(
Tom

Kabul edildi ve kaldırıldı!
thecarpy

0

Macos'un neden standart C işlevselliği yerine bunu kullandığından emin olmasam da, yıllar önce "Mac OS X Unleashed" de okuduğumun doğru olduğunu varsayarsak, yeni bir şey öğrendim.

Lütfen aşağıdaki basit C programına bakın:

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

Programı derleyin, arka planda çalıştırın ve hızlı bir şekilde mv file.txt file2.txtprogram yazdırmadan ÖNCE "Bitmiş uyku, dosyaya yazma." (10 saniyeniz var)

file2.txtMetin dosyaya yazdırılmadan önce taşınmasına rağmen programınızın çıktısına sahip olduğuna dikkat edin (dosya tanımlayıcı aracılığıyla).

$ 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

YASAL UYARI: "Dahil" listesini bulamadım, bu bir nokta kanıtlamak için hızla birlikte kesmek oldu.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.