GNU Stow có thể sử dụng một thư mục stow là một liên kết tượng trưng không?


10

Hãy xem xét kịch bản này.

#! /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

Đầu ra là

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

Trước khi chạy stow, nó trông như thế này:

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

Sau khi chạy stow, mylinktôi mong đợi nó trông như thế này:

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

Tuy nhiên, thay vào đó, nó trông như thế này:

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

Có vẻ như stowlệnh giải quyết realpath của thư mục gói, vì vậy thay vì chỉ vào ../mylink/package/filenó trỏ đến ../mydir/package/file.

Điều này có ý nghĩa cho việc tránh quá nhiều sự gián tiếp, nhưng nó xảy ra âm thầm và có thể không phải lúc nào cũng được mong muốn. Có cách nào để khắc phục hành vi này không?

Chỉnh sửa: Theo yêu cầu, tôi sẽ mô tả một trường hợp sử dụng ví dụ trong đó việc giải quyết đường dẫn thực sự bất tiện.

Liên kết tượng trưng đôi khi được sử dụng để tương thích . Debian thậm chí còn nói về điều này trong chính sách chính thức . Thông thường mục tiêu là một tệp duy nhất, nhưng đôi khi nó là một thư mục . Tôi tình cờ có một vài trăm trên hệ thống của tôi /usr/share/doc/một mình:

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

Hành vi mặc định stowlà ổn miễn là mục tiêu symlink không bị di chuyển. Nhưng đôi khi thư mục được nhắm mục tiêu mong muốn được di chuyển. Ví dụ, trên Debian, vim-runtimegói cài đặt các tệp trong / usr / share / vim / trong một thư mục phụ thuộc vào phiên bản, chẳng hạn như /usr/share/vim/vim64cho phiên bản 6.4. Tuy nhiên, gói cũng sẽ cập nhật một liên kết tượng trưng tại /usr/share/vim/vimcurrentđó nhọn lên phiên bản hiện hành. Điều này có nghĩa là một liên kết tượng trưng đến, nói

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

sẽ bị hỏng khi bản phát hành tiếp theo của Debian nâng cấp nó lên

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

nhưng một liên kết đến

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

sẽ làm việc trong cả hai phiên bản.

stowsử dụng đường dẫn chính tắc tuyệt đối của thư mục stow, nên một lời gọi như

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

sẽ dẫn đến các liên kết tượng trưng như, ví dụ:

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

không như thế này:

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

(Động lực cho việc sử dụng stowtrên vimcurrent/docs là để có thể hòa nhập ghi chú vim riêng tôi cùng với liên kết tượng trưng cho tài liệu hiện hành.) Lưu ý rằng các vimcurrentliên kết tượng trưng tương thích là không có mặt lâu hơn trong các bản phân phối Debian hiện tại , mặc dù nó có thể là ở những người khác như Arch Linux ; Tôi không chắc. Trong mọi trường hợp, đây là một kịch bản đưa ra ý tưởng chung cho tài liệu 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

Đầu ra là:

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

Theo giả thuyết, stowcó thể có một lá cờ được gọi là --no-realpath, vì vậy, đầu ra sẽ trông giống như thế này:

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

Đối với các ví dụ khác về các liên kết tương thích thay đổi theo từng phiên bản, đây là hai ví dụ nữa tôi biết về máy tính xách tay của mình:

$ 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

Để giải quyết trường hợp symlink-points-to-symlink:

#! /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

sản xuất:

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

và sau đó:

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

sản xuất:

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

trong khi

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

sẽ tạo ra điều này:

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

Vì vậy, trong --no-realpathhành vi giả thuyết, nó sẽ coi thư mục stow như một thư mục thông thường.

Tính năng này sẽ được áp dụng trong một kịch bản trong đó

1) thư mục stow phải là một liên kết tượng trưng và

2) mong muốn duy trì liên kết đó trong các liên kết tượng trưng được tạo.

Mặc dù tôi không coi việc thiếu tính năng này là một thiếu sót lớn stow, tôi hy vọng rằng ví dụ này làm rõ tính hữu dụng tiềm năng của việc không phải lúc nào cũng giải quyết các đường dẫn chính tắc.


Xin vui lòng bạn có thể đưa ra một trường hợp sử dụng ví dụ trong đó việc tránh sự gián tiếp này sẽ hữu ích? Điều gì xảy ra nếu mylinkthay vào đó được liên kết với nhau mylink2mà lần lượt được liên kết với nhau mydir? Làm thế nào Stow quyết định liệu nó nên tạo liên kết tượng trưng trỏ đến ../mylink/package/filehoặc ../mylink2/package/filehay ../mydir/package/file?
Adam Spiers

@AdamSpiers Tôi hy vọng điều đó sẽ giúp phần nào. Tôi cũng có thể đặt cái này lên bộ theo dõi vấn đề Github, nếu bạn thích.
Nathaniel M. Beaver

Cảm ơn @Nathaniel. Vâng, xin vui lòng sẽ hữu ích!
Adam Spiers

Câu trả lời:


7

Bây giờ, không có cách nào.

Trong nội bộ, stowtìm đường dẫn chính tắc tuyệt đối của đường dẫn đã cho bằng cách sử dụng chdir để di chuyển vào đường dẫn, sau đó sử dụng hàm getcwd () từ mô-đun POSIX, là giao diện Perl cho POSIX getcwd () , để lấy tên đường dẫn tuyệt đối.

Như POSIX đã chỉ định, tên đường dẫn sẽ không chứa các thành phần là .hoặc .., hoặc là các liên kết tượng trưng.


1
Đề xuất về cách khắc phục việc thực hiện để xử lý việc này một cách chính xác rất đáng hoan nghênh. Yêu cầu kéo thậm chí còn được chào đón nhiều hơn! :-) Để tham khảo, vấn đề đã được báo cáo ở đây: github.com/aspiers/stow/issues/11
Adam Spiers
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.