Может ли GNU Stow использовать каталог Stow, который является символической ссылкой?

10

Рассмотрим этот сценарий.

#! /usr/bin/env bash

mkdir -p target
mkdir -p mydir/package/
touch mydir/package/file

ln --symbolic mydir mylink
file mylink

stow --verbose --dir=./mylink --target=./target package

file target/file

Выход

mylink: symbolic link to mydir
LINK: file => ../mydir/package/file
target/file: symbolic link to ../mydir/package/file

Перед запуском stowэто выглядит так:

.
├── mydir
│   └── package
│       └── file
├── mylink -> mydir
└── target

После запуска stow, на mylink, я ожидал , что он выглядит следующим образом :

.
├── mydir
│   └── package
│       └── file
├── mylink -> mydir
└── target
    └── file -> ../mylink/package/file

Однако вместо этого это выглядит так:

.
├── mydir
│   └── package
│       └── file
├── mylink -> mydir
└── target
    └── file -> ../mydir/package/file

Кажется, что stowкоманда разрешает реальный путь к каталогу пакета, поэтому вместо указания на ../mylink/package/fileнее указывает ../mydir/package/file.

Это имеет смысл избегать слишком большого количества косвенных указаний, но это происходит тихо и не всегда желательно. Есть ли способ обойти это поведение?

Редактировать: в соответствии с запросом, я опишу пример использования, в котором разрешение реального пути неудобно.

Символические ссылки иногда используются для совместимости . Debian даже говорит об этом в официальной политике . Часто целью является отдельный файл, но иногда это каталог . У меня в системе несколько сотен в /usr/share/doc/одиночестве:

$ find /usr/share/doc -xtype d -type l | wc -l
325

Поведение по умолчанию stowхорошо, если цель символической ссылки не перемещается. Но иногда нужный целевой каталог действительно перемещается. Например, в Debian vim-runtimeпакет устанавливает файлы в / usr / share / vim / в каталог, который зависит от версии, например, /usr/share/vim/vim64для версии 6.4. Тем не менее, пакет будет также обновить символьную ссылку на /usr/share/vim/vimcurrentчто указывает на текущую версию. Это означает, что символическая ссылка указывает, скажем,

/usr/share/vim/vim64/doc/cmdline.txt

сломается, когда следующий выпуск Debian обновит его до

/usr/share/vim/vim70/doc/cmdline.txt

но символическая ссылка на

/usr/share/vim/vimcurrent/doc/cmdline.txt

будет работать в обеих версиях.

Поскольку stowиспользуется абсолютный канонический путь к каталогу Stow, такой вызов, как

stow --dir=/usr/share/vim/vimcurrent --target=./my-vim-docs doc

приведет к символическим ссылкам, например, так:

$ file cmdline.txt
cmdline.txt: symbolic link to ../../../../../usr/share/vim/vim64/doc/cmdline.txt

не так:

$ file cmdline.txt
cmdline.txt: symbolic link to ../../../../../usr/share/vim/vimcurrent/doc/cmdline.txt

(Мотивация использования stowon vimcurrent/docs состоит в том, чтобы иметь возможность смешивать мои собственные заметки vim вместе с символическими ссылками на текущую документацию.) Обратите внимание, что vimcurrentсимволическая ссылка совместимости больше не присутствует в текущих дистрибутивах Debian , хотя она может быть в других, таких как Arch Linux ; Я не уверен. В любом случае, вот скрипт, который дает общую идею для документации vim:

#! /usr/bin/env bash
mkdir -p target
ln --symbolic /usr/share/vim/vim80 vimcurrent
stow --verbose --dir=./vimcurrent --target=./target pack
file target/dist

Выход:

LINK: dist => ../../../../../usr/share/vim/vim80/pack/dist
target/dist: symbolic link to ../../../../../usr/share/vim/vim80/pack/dist

Гипотетически, stowмог бы иметь флаг, скажем, скажем --no-realpath, поэтому вывод будет выглядеть примерно так:

LINK: dist => ./vimcurrent/pack/dist
target/dist: symbolic link to ./vimcurrent/pack/dist

Для других примеров символических ссылок совместимости, которые меняются с каждой версией, вот еще два, которые я знаю на моем ноутбуке:

$ file /usr/share/go
/usr/share/go: symbolic link to go-1.10
$ file /usr/share/mscore
/usr/share/mscore: symbolic link to mscore-2.1

Чтобы обратиться к случаю символических ссылок на символическую ссылку:

#! /usr/bin/env bash
mkdir -p target
mkdir -p mydir/package/
touch mydir/package/file
ln --symbolic mydir mylink
ln --symbolic mylink mylink2
namei mylink2

производит:

f: mylink2
 l mylink2 -> mylink
   l mylink -> mydir
     d mydir

а потом:

$ stow --verbose --dir=./mylink2 --target=./target package
$ file target/file

производит:

LINK: file => ../mydir/package/file
target/file: symbolic link to ../mydir/package/file

в то время как

$ stow --no-realpath --verbose --dir=./mylink2 --target=./target package
$ file target/file

будет производить это:

LINK: file => ../mylink2/package/file
target/file: symbolic link to ../mylink2/package/file

Таким образом, в гипотетическом --no-realpathповедении он будет рассматривать каталог-каталог как обычный каталог.

Эта функция будет применима в сценарии, где

1) каталог размещения должен быть символической ссылкой, и

2) желательно сохранить эту ссылку в сгенерированных символических ссылках.

Хотя я не считаю отсутствие этой функции большим недостатком stow, я надеюсь, что этот пример проясняет потенциальную полезность не всегда решения канонических путей.

Натаниэль М. Бивер
источник
Пожалуйста, не могли бы вы привести пример использования, где было бы полезно избежать этого косвенного обращения? Что, если mylinkвместо этого есть символическая ссылка на mylink2которую в свою очередь символическая ссылка mydir? Как Стоу решить, следует ли создавать символические ссылки, указывающие на ../mylink/package/fileили ../mylink2/package/fileили ../mydir/package/file?
Адам
@ AdamSpiers Надеюсь, это поможет. Я мог бы поставить это и на трекер Github, если вы предпочитаете.
Натаниэль М. Бивер
Спасибо, Натаниэль. Да, пожалуйста, это было бы полезно!
Адам
1
@AdamSpiers Готово! github.com/aspiers/stow/issues/11#issuecomment-507073811
Натаниэль М. Бивер

Ответы:

7

Пока нет пути.

Внутренне stowнайдите абсолютный канонический путь заданного пути с помощью chdir для перемещения по пути, затем используйте функцию getcwd () из модуля POSIX, который является интерфейсом Perl для POSIX getcwd () , чтобы получить абсолютное имя пути.

Как указано POSIX, имя пути не должно содержать компоненты , которые являются .или .., или являются символическими ссылками.

cuonglm
источник
1
Предложения о том, как исправить реализацию для правильной обработки, очень приветствуются. Запросы на тягу еще более приветствуются! :-) Для справки, проблема была сообщена здесь: github.com/aspiers/stow/issues/11
Адам Спирс