Git Bash Shell не создает символические ссылки
Когда я пытаюсь создать символическую ссылку из оболочки Git Bash, она терпит неудачу каждый раз все время:
$ ln -s /c/Users/bzisad0/Work testlink
ln: creating symbolic link `testlink' to `/c/Users/bzisad0/Work': Permission denied
Единственное, что он делает, помимо сообщения об ошибке, - создать пустой каталог с именем (в данном случае) testlink
.
Я не вижу никаких проблем с исполняемым файлом ln
. Например, он принадлежит мне и помечен как исполняемый файл:
$ which ln
/bin/ln
$ ls -hal /bin/ln
-rwxr-xr-x 1 BZISAD0 Administ 71k Sep 5 11:55 /bin/ln
У меня также есть текущий каталог (~
, который /c/Users/bzisad0
):
$ ls -dhal .
drwxr-xr-x 115 BZISAD0 Administ 40k Sep 5 12:23 .
У меня есть права администратора, и я попытался открыть оболочку Git Bash с "Запуск от имени администратора", но это не имеет никакого значения.
Я попытался открыть свойства Windows для ln.exe
и установить уровень привилегий для "Запускать эту программу как администратор", но это не помогает.
Я перешел в свойства Security → Advanced в Windows и сделал себя (а не группу "Администраторы" ) владельцем, но это ничего не исправить.
Я в недоумении. Я не знаю, в конечном итоге это сообщение об ошибке происходит от ln
, от Bash или от Windows, или от того, как мне может не хватать разрешения. Как я могу понять это?
Ответы
Ответ 1
Возможно, хотя и крайне неудобно создавать символическую ссылку в MSYSGIT.
Во-первых, нам нужно убедиться, что мы в Windows. Вот пример функции для проверки того, что:
windows() { [[ -n "$WINDIR" ]]; }
Теперь мы не можем сделать cmd /C
, потому что MSYSGIT будет лелеять этот аргумент и превратить его в C:
. Кроме того, не стоит искушать использование /K
, он работает только в том случае, если у вас нет диска K:
.
Поэтому, пока он заменит это значение на аргументах программы, он не будет использоваться для heredocs. Мы можем использовать это в наших интересах:
if windows; then
cmd <<< "mklink /D \"${link%/}\" \"${target%/}\"" > /dev/null
else
ln -s "$target" "$link"
fi
Также: обратите внимание, что я включил /D
, потому что меня интересуют только символические ссылки каталога; Windows имеет это различие. С большим трудом вы можете написать функцию ln() { ... }
, которая обертывает Windows API и служит полным решением для вставки, но это... оставлено как упражнение для читателя.
Изменить: Как благодарность за принятый ответ, здесь более полная функция.
# 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 a directory or not. Infer that.
# Also: note that we convert `/` to `\`. In this case it 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 parameters are backwards.
ln -s "$2" "$1"
fi
fi
}
Также обратите внимание на несколько вещей:
- Я только что написал это и вкратце протестировал его на Win7 и Ubuntu, попробуйте сначала, если вы с 2015 года и используете Windows 9.
- NTFS имеет точки повторной обработки и точки соединения. Я выбрал точки повторной обработки, потому что это больше фактическая символическая ссылка и работает для файлов или каталогов, но точки соединения будут полезны для использования в XP, кроме как для каталогов.
- Некоторые файловые системы, в частности, FAT, не поддерживают символические ссылки. Современные версии Windows больше не поддерживают загрузку, но Windows и Linux могут их монтировать.
Бонусная функция: удалите ссылку.
# Remove a link, cross-platform.
rmlink() {
if windows; then
# Again, Windows needs to be told if it a file or directory.
if [[ -d "$1" ]]; then
rmdir "$1";
else
rm "$1"
fi
else
rm "$1"
fi
}
Ответ 2
Обходной путь - запустить mklink
из Bash. Это также позволяет вам создать символическую ссылку или соединение.
Позаботьтесь о том, чтобы отправить команду mklink
в качестве единственного аргумента cmd
...
cmd /c "mklink link target"
Вот варианты для 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.
Если вы хотите вместо этого создавать ссылки с помощью графического интерфейса... Я рекомендую Link Shell Extension, которая является плагином Windows Explorer для создания символических ссылок, жестких ссылок, переходов и точек монтирования тома. Я использую это в течение многих лет!
Симлинки могут быть спасением жизни, если на вашем системном диске C: есть SSD-диск меньшего размера, и вам нужно символически связать некоторые раздутые папки, которые не должны быть на SSD, с другими дисками. Я использую бесплатный WinDirStat, чтобы найти место на диске.
Ответ 3
Я считаю, что ln
, который поставляется с msysGit, просто пытается скопировать его аргументы, а не скриптировать ссылки. Это связано с тем, что ссылки работают (только) на файловых системах NTFS, а команда MSYS не хочет переопределять ln.
См., например, http://mingw.5.n7.nabble.com/symbolic-link-to-My-Documents-in-MSYS-td28492.html
Ответ 4
Для моей установки это Git для Windows 2.11.0, установленный в Windows 8.1 export MSYS=winsymlinks:nativestrict
делает то, что описано здесь: https://github.com/git-for-windows/git/pull/156 Это важно запускать оболочку Git Bash от имени администратора, поскольку в Windows только администраторы могут создавать символические ссылки. Итак, чтобы заставить tar -xf
работать и создать необходимые символические ссылки:
- Запустите Git Bash shell от имени администратора
- Запустите
export MSYS=winsymlinks:nativestrict
- Запустить смолу
Ответ 5
Так как это одна из верхних ссылок, которые возникают при поиске символических ссылок в Msys или git bash, я нашел ответ на добавление
set MSYS=winsymlinks:native
при вызове git-cmd.exe
(я запускаю ConEmu) или раскомментирую ту же строку в msys2_shell.bat
Ответ 6
Я предпочитаю Powershell CMD и решил поделиться версией PowerShell.
В моем случае это состоит из создания символических ссылок, связывающих файл ~/.$ с ~/dotfiles/$ file, для конфигурации dotfile. Я поместил это в сценарий .sh
и запустил его с помощью git-bash:
powershell New-Item -ItemType SymbolicLink\
-Path \$Home/.$file\
-Target \$Home/dotfiles/$file
Ответ 7
Расширение Camilo Martin anwser, так как вам нужно использовать параметр параметра /j для Windows 10; в противном случае вызов просто вернет "У вас недостаточно прав для выполнения этой операции".
Это работает для git bash 2.20.1.windows.1/MINGW64 (Windows 10) без прав администратора (если вы можете читать/писать как /old/path, так и /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