Su Windows 7 con Python 2.7 come posso rilevare se un percorso è un collegamento simbolico? Questo non funziona , dice che restituisce false se false o non supportate e il percorso che sto fornendo è sicuramente un collegamento simbolico quindi presumo che non sia supportato su Windows? Cosa posso fare?os.path.islink su windows con python
risposta
Il problema principale è che si sta utilizzando una versione vecchia di Python. Se si desidera attenersi a 2.x, non sarà in grado di sfruttare le nuove funzionalità aggiunte dopo l'inizio del 2010.
Una di queste funzionalità è la gestione dei collegamenti simbolici NTFS. Tale funzionalità è stata aggiunta in 3,2 alla fine del 2010. (Vedere la 3.2, 3.1 e 2.7 sorgente per i dettagli.)
Il motivo Python non ha gestito i collegamenti simbolici NTFS prima di allora è che non vi era nulla di simile fino alla fine del 2009. (IIRC, il supporto è stato incluso nel kernel 6.0, ma il supporto per l'utente richiede un service pack su Vista/2008, solo 7/2008R2 e successivi sono integrati. Inoltre, è necessario un MSVCRT nuovo-sufficiente per poter accedere a tale supporto per l'utente e Python ha una politica esplicita di non eseguire l'aggiornamento a nuove versioni di Visual Studio all'interno di una versione secondaria.
Il motivo per cui il codice non è stato riportato su 2.x è that there will never be a 2.8 e versioni di correzioni di errori come 2.7. 3 (o 2.7.4) non ottengono ne w caratteristiche, solo correzioni di bug.
Questo è stato segnalato come issue 13143 e la correzione prevista è modificare i documenti 2.7 per chiarire che islink
restituisce sempre False
su Windows.
Quindi, se si desidera leggere i collegamenti simbolici NTFS in Windows, eseguire l'aggiornamento a Python 3.2+ oppure utilizzare win32api
, ctypes
, ecc. Per farlo da soli.
Oppure, come suggerisce Martijn Pieters, invece di farlo da solo, utilizzare una libreria di terze parti come jaraco.windows
che lo fa e/o prendere in prestito their code.
Oppure, se lo si desidera, prendere in prestito il codice dal sorgente 3.2 e creare un modulo di estensione C attorno ad esso. Se si rintraccia da ntpath
a os
a nt
(che in realtà è posixmodule.c
), credo che il coraggio di esso sia in win32_xstat_impl
and win32_xstat_impl_w
.
Chi ha downvoted, si preoccupa di spiegare perché? – abarnert
fantastico! grazie abarnert – user391986
Devi essere disinformato. i punti di analisi esistono da Windows NT 5 (Windows 2000) con NTFS 3.0. Ed era funzionale. l'implementazione di Python è semplicemente pigra o anche disinformata. –
Questo è quello che ho finito per usare per determinare se un file o una directory è un collegamento in Windows 7:
def isLink(path):
if os.path.exists(path):
if os.path.isdir(path):
FILE_ATTRIBUTE_REPARSE_POINT = 0x0400
attributes = ctypes.windll.kernel32.GetFileAttributesW(unicode(path))
return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) > 0
else:
command = ['dir', path]
try:
with open(os.devnull, 'w') as NULL_FILE:
o0 = check_output(command, stderr=NULL_FILE, shell=True)
except CalledProcessError as e:
print e.output
return False
o1 = [s.strip() for s in o0.split('\n')]
if len(o1) < 6:
return False
else:
return 'SYMLINK' in o1[5]
else:
return False
EDIT: Modificato il codice come da suggerimenti di Zitrax e Annan
Vale la pena prendere 'CalledProcessError's da' check_output' quando il file non esiste. Puoi anche passare 'stderr = subprocess.PIPE' per nascondere l'output di errore che va allo stdin. Questa soluzione è davvero hacky, ma più funzionale rispetto all'altra risposta. – Annan
Questa risposta non funziona per verificare se una directory è un collegamento, seno il comando dir sarà solo elencare il contenuto. – Zitrax
@Zitrax: 'dir/al" percorso * "' funziona –
per le directory :
import os, ctypes
def IsSymlink(path):
FILE_ATTRIBUTE_REPARSE_POINT = 0x0400
return os.path.isdir(path) and (ctypes.windll.kernel32.GetFileAttributesW(unicode(path)) & FILE_ATTRIBUTE_REPARSE_POINT):
[Questo] (http://bugs.python.org/issue13143) può provid e un po 'di aiuto. – crayzeewulf
dare un'occhiata al pacchetto ['jaraco.windows'] (https://bitbucket.org/jaraco/jaraco.windows/src/default/jaraco/windows/filesystem/__init__.py); deve usare 'ctypes' per supportare questo. Python 3.2 * fa * supporta correttamente i collegamenti simbolici di Windows. –