Frage

Does python have a simple function for checking if a directory is an actual directory or if it's just an alias to another directory? I'm trying to list all files/folders in a directory but because of these alias folders, I'm getting a lost of stuff that looks like this:

/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle

Directory Alias

I know I can write a function that will compare paths and quit if it seems like I'm going in circles, but is there a simple function that does exactly that that I'm not aware of? E.g. os.isAlias( …pathname… )

Thanks!

War es hilfreich?

Lösung

Here's a version of os.path.realpath that works on Mac aliases as well as on symbolic links under Python 2:

from Carbon import File
def osx_realpath (path):
    return File.FSResolveAliasFile(path, True)[0].as_pathname()

If you call osx_realpath on each directory before you recurse into it you should avoid duplication. Alternatively you could define something like

def is_osx_realpath (path):
    return path == osx_realpath(path)

Here you have to worry a little about false negatives, however. If you filter for is_osx_realpath and the path you start with is an alias, your program will stop without looking at anything.

So far I don't know of a way to do this under Python 3. I have a question here where I'm hoping for an answer. Right now I can't do better than using subprocess.call to invoke something that does the check on the command line.

EDIT: I should add that not only is Carbon.File not available in Python 3, but it is deprecated and so is best avoided in Python 2 as well--however it's the most pragmatic solution I know of for Python 2 at present.

EDIT 2: here is a way to check if a file is an alias that I believe to be Python 3-friendly. However, I don't have code to resolve the alias. I believe you need PyObjC installed.

from AppKit import NSWorkspace
def is_alias (path):
    uti, err = NSWorkspace.sharedWorkspace().typeOfFile_error_(
        os.path.realpath(path), None)
    if err:
        raise Exception(unicode(err))
    else:
        return "com.apple.alias-file" == uti

(source)

Andere Tipps

The answer above is incorrect. While it is true that Finder reports symlinks as alias, they are distinct things.

Symlinks are a basic feature of UNIX, but alias are a Apple only feature. If you doubt this create a symlink to a directory and an alias. The symlink will be small typically 50-100 bytes, whereas the alias can be several MB.

os.path.islink( … ) will report symlinks, but not alias.

I am not sure how you would find them in Python, but the following link shows other methods.

https://stackoverflow.com/a/21151368/838253

You can check whether a file or directory is an alias with the GetFileInfo command in Mac OS X. GetFileInfo -aa foo prints a line with "1" if foo is an alias and "0" if not.

import subprocess

def is_alias(path):
    return subprocess.check_output(["GetFileInfo", "-aa", path]) == "1\n"

Seems a little sad to spawn a process for every check, but I think this works with versions of Mac OS X since probably 10.4.4 (2006), 32-bit, 64-bit, Python 2 and Python 3. The version of GetFileInfo I have (from 2009) is a "universal" i386 + PPC binary.

GetFileInfo is part of Xcode, which is large, but you can download the command-line tools separately (see the "Separate Download" section here).

https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/GetFileInfo.1.html

Old question, but I just ran into this myself.

I have no perfect method for checking if the file is an alias, however, if using mimetypes, python will return None for an alias or a symlink. Might be useful in some situations. I've only tested this in python 3.8 on macOS Big Sur.

import mimetypes

for idx, f in enumerate(filepaths):
    type = mimetypes.guess_type(f)[0]
    print(f"type is: {type}")

returns (without my added comments):

type is: None # <-- Folder Alias
type is: None # <-- File Alias
type is: text/x-python
type is: None # <-- Folder Alias
type is: video/mp4
type is: image/png
type is: None # <-- Folder Alias
type is: None # <-- Symlink
type is: image/png
type is: application/zip
type is: image/png
type is: image/jpeg
type is: None # <-- Symlink

I ran some files through exiftool just to see what types they returned, and aliases and symlinks both showed the following:

File Type                       : ALIAS
File Type Extension             : alias
MIME Type                       : application/x-macos

You might be able to init the mimetypes for these, but haven't tested and not sure if it will give false positives if anything else shows up as application/x-macos

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top