Lorsque j'essaie de créer un lien symbolique à partir du shell Git Bash, il échoue à chaque fois:
$ ln -s /c/Users/bzisad0/Work testlink
ln: creating symbolic link `testlink' to `/c/Users/bzisad0/Work': Permission denied
La seule chose qu'il fait, en plus de donner le message d'erreur, est de créer un répertoire vide nommé (dans ce cas) testlink
.
Je ne vois aucun problème avec l'exécutable ln
. Par exemple, il est la propriété de moi et marqué comme exécutable:
$ which ln
/bin/ln
$ ls -hal /bin/ln
-rwxr-xr-x 1 BZISAD0 Administ 71k Sep 5 11:55 /bin/ln
Je possède également le répertoire actuel (~
, qui est /c/Users/bzisad0
):
$ ls -dhal .
drwxr-xr-x 115 BZISAD0 Administ 40k Sep 5 12:23 .
J'ai des droits administratifs et j'ai essayé d'ouvrir le shell Git Bash avec "Exécuter en tant qu'administrateur", mais cela ne fait aucune différence.
J'ai essayé d'ouvrir les propriétés Windows pour ln.exe
et de définir le niveau de privilège sur "Exécuter ce programme en tant qu'administrateur", mais cela n'aide pas.
Je suis allé dans les propriétés de sécurité -> avancées de Windows et je me suis fait propriétaire (plutôt que du groupe des administrateurs), mais cela ne règle rien non plus.
Je suis à perte. Je ne sais pas si ce message d'erreur vient finalement de ln
, de Bash ou de Windows, ou comment je pourrais éventuellement ne pas avoir l'autorisation. Comment puis-je aller au fond des choses?
Il est possible, mais extrêmement gênant, de créer un lien symbolique dans MSYSGIT.
Premièrement, nous devons nous assurer que nous sommes sur Windows. Voici un exemple de fonction pour vérifier cela:
windows() { [[ -n "$WINDIR" ]]; }
Maintenant, nous ne pouvons pas faire cmd /C
, car MSYSGIT forniquera avec cet argument et le transformera en C:
. En outre, ne soyez pas tenté d'utiliser /K
, cela ne fonctionne que si vous n'avez pas de lecteur K:
.
Ainsi, bien qu'elle remplace cette valeur sur les arguments du programme, elle ne le sera pas sur heredocs. Nous pouvons utiliser ceci à notre avantage:
if windows; then
cmd <<< "mklink /D \"${link%/}\" \"${target%/}\"" > /dev/null
else
ln -s "$target" "$link"
fi
Aussi: notez que j'ai inclus /D
parce que les liens symboliques du répertoire m'intéressent uniquement; Windows a cette distinction. Avec beaucoup d'effort, vous pourriez écrire une fonction ln() { ... }
qui englobe l'API Windows et constitue une solution complète, mais c'est un exercice pour le lecteur.
Edit: En guise de remerciement pour la réponse acceptée, voici une fonction plus complète.
# We still need this.
windows() { [[ -n "$WINDIR" ]]; }
# Cross-platform symlink function. With one parameter, it will check
# whether the parameter is a symlink. With two parameters, it will create
# a symlink to a file or directory, with syntax: link $linkname $target
link() {
if [[ -z "$2" ]]; then
# Link-checking mode.
if windows; then
fsutil reparsepoint query "$1" > /dev/null
else
[[ -h "$1" ]]
fi
else
# Link-creation mode.
if windows; then
# Windows needs to be told if it's a directory or not. Infer that.
# Also: note that we convert `/` to `\`. In this case it's necessary.
if [[ -d "$2" ]]; then
cmd <<< "mklink /D \"$1\" \"${2//\//\\}\"" > /dev/null
else
cmd <<< "mklink \"$1\" \"${2//\//\\}\"" > /dev/null
fi
else
# You know what? I think ln's parameters are backwards.
ln -s "$2" "$1"
fi
fi
}
Notez également quelques points:
Fonction bonus: supprimer un lien.
# Remove a link, cross-platform.
rmlink() {
if windows; then
# Again, Windows needs to be told if it's a file or directory.
if [[ -d "$1" ]]; then
rmdir "$1";
else
rm "$1"
fi
else
rm "$1"
fi
}
Une solution de contournement consiste à exécuter mklink
à partir de Bash. Cela vous permet également de créer un lien symbolique ou une jonction .
Prenez soin d’envoyer la commande mklink
en tant qu’argument unique à cmd
...
cmd /c "mklink link target"
Voici les options pour mklink
...
$ cmd /c mklink
Creates a symbolic link.
MKLINK [[/D] | [/H] | [/J]] Link Target
/D Creates a directory symbolic link. Default is a file
symbolic link.
/H Creates a hard link instead of a symbolic link.
/J Creates a Directory Junction.
Link specifies the new symbolic link name.
Target specifies the path (relative or absolute) that the new link
refers to.
Si vous souhaitez plutôt créer des liens via une interface graphique ... Je recommande Link Shell Extension qui est un plug-in de l'explorateur Windows permettant de créer des liens symboliques, des liens physiques, des jonctions et des points de montage en volume. Je l'utilise depuis des années!
Les liens symboliques peuvent vous sauver la vie si vous avez un lecteur SSD plus petit sur votre lecteur système C: et que vous devez créer un lien symbolique vers des dossiers surchargés qui ne nécessitent pas nécessairement d'être en mode SSD sur d'autres lecteurs. J'utilise le répertoire libre WinDirStat pour trouver les réserveurs d'espace disque.
Je crois que la ln
fournie avec msysGit essaie simplement de copier ses arguments, plutôt que de manipuler des liens. En effet, les liens fonctionnent uniquement (en quelque sorte) sur les systèmes de fichiers NTFS, et l’équipe MSYS ne souhaitait pas réimplémenter ln.
Voir, par exemple, http://mingw.5.n7.nabble.com/symbolic-link-to-My-Documents-in-MSYS-td28492.html
Pour ma configuration, c'est Git pour Windows 2.11.0 installé sur Windows 8.1 export MSYS=winsymlinks:nativestrict
fait l'affaire comme expliqué ici: https://github.com/git-for-windows/git/pull/156 Il est important de lancer Git Bash Shell en tant qu'administrateur, car sous Windows, seuls les administrateurs pouvaient créer les liens symboliques . Ainsi, pour que tar -xf
fonctionne et crée les liens symboliques requis:
export MSYS=winsymlinks:nativestrict
Comme il s’agit d’un des principaux liens qui apparaissent lors de la création de liens symboliques dans Msys ou git bash, j’ai trouvé la réponse à ajouter set MSYS=winsymlinks:native
lorsqu’appelez git-cmd.exe
(je lance ConEmu) ou décommentez la même ligne dans le msys2_Shell.bat
Étendre la réponse de Camilo Martin à l'utilisation du commutateur de paramètres/j pour Windows 10; sinon, l'appel retournera simplement "Vous ne disposez pas du privilège suffisant pour effectuer cette opération".
Cela fonctionne pour git bash 2.20.1.windows.1/MINGW64 (Windows 10) sans droits d’administrateur (si vous pouvez lire/écrire les deux/old/path et/link/path:
original_folder=$(cygpath -w "/old/path")
create_link_new_folder=$(cygpath -w "/link/path")
cmd <<< "mklink /j \"${create_link_new_folder}\" \"${original_folder}\"" > /dev/null
Je préfère Powershell à CMD et je pensais partager la version powershell de ce logiciel.
Dans mon cas, il s'agit de créer des liens symboliques reliant le fichier ~ /.$ au fichier ~/dotfiles/$, Pour les configurations de fichiers points. J'ai mis cela dans un script .sh
et l'ai exécuté avec git-bash:
powershell New-Item -ItemType SymbolicLink\
-Path \$Home/.$file\
-Target \$Home/dotfiles/$file