1
votes

Comment puis-je trouver la cible d'un lien symbolique Linux en C #

En C #, j'ai besoin de trouver le chemin réel d'un fichier / répertoire sous Linux qui pourrait se trouver de l'autre côté d'un lien symbolique.

J'ai trouvé la solution à cela sur Windows à Comment obtenir la cible d'un lien symbolique (ou Reparse Point) en utilisant .Net? , mais cela pour des raisons assez évidentes ne fonctionnera pas sous Linux. Je pourrais appeler readlink, mais il se peut que je doive souvent le faire et je détesterais passer tout ce temps à gérer des processus externes.

J'aimerais quelque chose comme ça:

/link -> /actual/path

Si le lien symbolique est quelque chose comme:

string GetFinalPathName(string inputPath);

Et j'appelle GetFinalPathName("/link/myfile.txt") il devrait retourner "/actual/path/myfile.txt".

Comment puis-je trouver la cible d'un lien symbolique Linux en C #?


0 commentaires

3 Réponses :


0
votes

Je pense que vous devrez créer un projet C / C ++ natif qui exporte un wrapper pour la fonction Linux readlink (), puis utiliser l'appel de plate-forme pour l'appeler à partir de C #. Cela semble être la manière dont le CLR le gère. Malheureusement, je ne pense pas que vous puissiez simplement appeler leur implémentation: code CLR Unix ReadLink


0 commentaires

1
votes

J'ai découvert une solution.

Commencez avec le package nuget mono.posix-4.5:

https://www.nuget.org/packages/Mono.Posix-4.5/

Ensuite, la solution était simple:

return Mono.Unix.UnixPath.GetRealPath(path);


1 commentaires

Plus d'informations sur Mono.Posix: Mono.Posix.NETStandard est plus à jour et prend en charge .NET Standard. Malgré l'espace de noms Mono, cela semble être la manière approuvée par Microsoft de passer des appels Posix / Unix. Détails dans ce numéro .



0
votes

Bien que la bibliothèque NuGet Mono.Posix.NETStandard puisse faire le travail, utilisez-la avec prudence. À mon avis, cela produit des résultats inattendus et contre-intuitifs. Vous trouverez ci-dessous quelques tests avec la sortie de GetRealPath() et des fonctions similaires sur Max OSX Catalina (v.10.15.7).

Sur la base de ces tests, il semble que vous ne pouvez pas simplement fournir le chemin complet de GetRealPath() ou d'autres fonctions et obtenir le chemin du fichier cible final avec les liens symboliques résolus en conséquence. Au lieu de cela, vous devez tester chaque dossier du chemin à l'aide de GetRealPath() ou GetCompleteRealPath() .

Depuis le terminal:

GetRealPath() => /Volumes/Mac HD/Users/Shared/existing.txt
GetCompleteRealPath() => //Users/Shared/existing.txt
GetCanonicalPath() => /Volumes/Mac HD/Users/Shared/existing.txt

À partir des tests C #:

Chemin d'entrée: /Volumes/Mac HD <== c'est le volume racine

GetRealPath() => /Volumes/Mac HD/
GetCompleteRealPath() => /
GetCanonicalPath() => /Volumes/Mac HD

Chemin d'entrée: /Volumes/Mac HD/ <== la barre oblique de fin produit des résultats inattendus

GetRealPath() => /
GetCompleteRealPath() => /
GetCanonicalPath() => /Volumes/Mac HD

Chemin d'entrée: /Volumes/Mac HD/Users/Shared/existing.txt <== le fichier existant dans le volume lié par un lien symbolique donne "//" dans GetCompleteRealPath()

$ pwd
/Volumes
$ ls -l 
total 0 
drwxr-xr-x  32 root    wheel  1156 Oct  7 17:12 HD2
lrwxr-xr-x   1 root    wheel     1 Nov 12 22:14 Mac HD -> /


0 commentaires