Làm cách nào để chỉnh sửa liên kết tượng trưng?


64

Hiểu biết cơ bản của tôi về một liên kết tượng trưng là một tệp đặc biệt, một tệp chứa đường dẫn chuỗi đến tệp khác. VFS của kernel trừu tượng hóa rất nhiều thứ đó nhưng có lý do nào khiến các liên kết tượng trưng dường như không thể chỉnh sửa?

Nói cách khác: Tôi có thể chỉnh sửa một liên kết tượng trưng không? Nếu không, tai sao không?


Tôi hiểu rằng có nhiều cách khác nhau để thay thế các liên kết tượng trưng (hai phương án hiện đang có trong phần câu trả lời) nhưng sẽ rất thú vị khi có một lời giải thích về lý do tại sao thay thế dường như là cách duy nhất để đối phó với các liên kết tượng trưng. Tại sao bạn không thể thay đổi nơi họ chỉ?


Hiểu biết của bạn là một chút hạn chế; lý do duy nhất nó được gọi là "tập tin" là vì không có từ nào tốt hơn cho nó.
Shadur

5
Không giống như sự tàn bạo đáng xấu hổ đó là biến thể của windows, các liên kết tượng trưng theo kiểu posix hoạt động trên / trong chính lớp hệ thống tập tin. Cách duy nhất để chỉnh sửa một là sẽ chỉnh sửa trực tiếp hệ thống tập tin - và nói chung là không đáng.
Shadur

Các tệp @Shadur .lnk không thực sự là các liên kết tượng trưng để bắt đầu (và NTFS đã có các liên kết phù hợp kể từ Vista); chúng giống như các phím tắt để thực thi các lệnh, cho dù đó là thay đổi vào một thư mục cụ thể hoặc bắt đầu một chương trình với các đối số cụ thể và với một CWD nhất định.
JAB

Câu trả lời:


36

Cho rằng -fchỉ cần thay thế im lặng, bạn có thể thay thế nguyên tử bằng mv -T(-T làm cho nó hoạt động ngay cả khi /loc.../link là một thư mục) :

ln -s /location/to/link linkname
# ... 
ln -s /location/to/link2 newlink
mv -T newlink linkname

linkname có thể truy cập trong suốt quá trình.


7
Điều đó giúp bạn thay thế nguyên tử, mặc dù bạn vẫn đang thực hiện thay thế thay vì chỉnh sửa (liên kết mới có số inode mới).
psusi

2
@psusi Tôi hoàn toàn đồng ý, đó chỉ là một lựa chọn tốt hơn về mặt kỹ thuật so với câu trả lời khác trong một số tình huống.
Oli

Nếu bạn đang chuyển hướng liên kết đến một điểm đến khác thì việc thay đổi số inode có vẻ như là một thay đổi nhỏ.
ams

4
Giả định đó linknamekhông phải là một liên kết tượng trưng đến một thư mục. Sử dụng -Ttùy chọn mvnếu trên GNU hoặc -hnếu trên FreeBSD để tránh điều đó. Lưu ý rằng như thế ln -sfkhông bảo vệ các quyền của liên kết (trên các hệ thống có ý nghĩa).
Stéphane Chazelas

Một giải pháp khác để thay đổi symlink cho thư mục là sử dụng -ncác tùy chọn, ví dụ : ln -sfn DESTINATION_DIRECTORY LINK_NAME. Đọc thêm về Askubfox.com/a/186227/69004
sobi3ch

22

Nếu bằng cách chỉnh sửa, bạn có nghĩa là thay đổi tệp mà nó trỏ đến, thì có, bạn có thể:

$ ln -s .bashrc test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 7 2009-09-23 17:12 test -> .bashrc
$ ln -s .profile test
ln: creating symbolic link `test': File exists
$ ln -s -f .profile test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 8 2009-09-23 17:12 test -> .profile

Các -ftham số ( --force) khi truyền cho ln nó gây ra nó để gọi unlink()cuộc gọi hệ thống ngay trước khisymlink()

Lấy từ câu trả lời tràn ngăn xếp sau đây .


9
Tôi nghĩ thật đáng nghi nếu điều này có thể được coi là "chỉnh sửa", vì unlink (); symlink (); không phải là nguyên tử, vì vậy có một khoảng thời gian rất nhỏ trong đó liên kết không tồn tại.
phát lại

@ mauro.stettler Vâng, bạn đã đúng. Nhưng tôi đoán rằng điều này phụ thuộc vào quan điểm của bạn. Nếu bạn chỉ đưa kết quả cuối cùng vào tài khoản, thì có lẽ bạn có thể coi đó là chỉnh sửa, không có điều gì khác được xem xét.
NlightNFotis

1
Phần trích dẫn từ bài viết Hệ thống chia sẻ thời gian Unix mô tả các liên kết cứng . Chúng hoàn toàn khác với các liên kết tượng trưng (symlink) mà OP đã hỏi.
Ansgar Esztermann

4
Lưu ý rằng testmục tiêu của nó giả định không phải là một thư mục. Nếu không ln -s -f .profile testsẽ tạo một .profileliên kết tượng trưng trong thư mục đó. GNU lncó một -Ttùy chọn để tránh điều đó.
Stéphane Chazelas

9

Liên kết tượng trưng cần phải được sửa đổi nguyên tử. Nếu bạn đang viết nửa chừng, họ sẽ không làm việc. Nội dung của một liên kết tượng trưng là khá nhỏ (nhiều nhất là 4095 ký tự trên Linux: độ dài tối đa của một đường dẫn đến một tệp), do đó sẽ có rất ít điểm trong việc chỉnh sửa một phần của liên kết tượng trưng ở cấp hạt nhân. Do đó, kernel không cung cấp bất kỳ giao diện nào để chỉnh sửa một liên kết tượng trưng, ​​chỉ có một giao diện để tạo một giao diện mới, symlinkcuộc gọi hệ thống (cộng với giao diện chung unlinkđể xóa bất kỳ tệp nào).

Cuộc symlinkgọi hệ thống chỉ tạo ra một liên kết tượng trưng mới, nó không xóa bất kỳ tập tin hiện có. Điều này gây khó chịu, nhưng phù hợp với các lệnh gọi hệ thống khác để tạo các tệp như open(có thể tạo tệp mới hoặc cắt bớt tệp hiện có, nhưng không thay thế tệp hiện có bằng tệp mới tạo) và mkdir.

Trong shell, như bạn đã phát hiện ra , trong khi bạn không thể thay thế một liên kết tượng trưng bằng lnlệnh ( ln -sfhủy liên kết tệp trước đó sau đó tạo liên kết tượng trưng), trước tiên bạn có thể thực hiện bằng cách tạo liên kết tượng trưng dưới tên tạm thời và sau đó di chuyển nó vào vị trí

tmp=$(TMPDIR=$(dirname -- "$link") mktemp)
ln -sf -- "$target" "$tmp"
mv -f "$tmp" "$link"

2
mv -f(như ln -sf) sẽ không làm những gì bạn muốn nếu $linktrỏ đến một thư mục. GNU ln và mv có một -Tđiều đó. mv(đổi tên cuộc gọi hệ thống) sẽ luôn thay đổi inode của $linkwhile ln -sfT(unlink + symlink) có thể sử dụng lại như cũ.
Stéphane Chazelas

0

Về mặt kỹ thuật, không có lệnh tích hợp để chỉnh sửa một liên kết tượng trưng hiện có. Nó có thể dễ dàng đạt được với một vài lệnh ngắn.

Đây là một hàm bash / zsh nhỏ mà tôi đã viết để cập nhật một liên kết tượng trưng hiện có:

# -----------------------------------------
# Edit an existing symbolic link
#
# @1 = Name of symbolic link to edit
# @2 = Full destination path to update existing symlink with 
# -----------------------------------------
function edit-symlink () {
    if [ -z "$1" ]; then
        echo "Name of symbolic link you would like to edit:"
        read LINK
    else
        LINK="$1"
    fi
    LINKTMP="$LINK-tmp"
    if [ -z "$2" ]; then
        echo "Full destination path to update existing symlink with:"
        read DEST
    else
        DEST="$2"
    fi
    ln -s $DEST $LINKTMP
    rm $LINK
    mv $LINKTMP $LINK
    printf "Updated $LINK to point to new destination -> $DEST"
}

Xin lỗi, nhưng câu trả lời của bạn chỉ có liên quan đến câu hỏi từ xa.
dùng2233709

Xin chào @ user2233709 - câu hỏi của người dùng " Làm cách nào tôi có thể chỉnh sửa liên kết tượng trưng? " Đã được trả lời rõ ràng trong câu đầu tiên cũng như bằng cách cung cấp giải pháp. Bạn có quan tâm đến xây dựng?
blizzrdof77

2
Bạn đã thực sự đọc câu hỏi? Đó là về việc có thể sửa đổi một liên kết tượng trưng, ​​thay vì thay thế nó. Giải pháp được đề xuất của bạn là một tập lệnh thay thế một liên kết tượng trưng.
dùng2233709

0

Giả sử tên liên kết tồn tại là kết quả của việc đã hoàn thành (trong quá khứ):

 ln -s   /the/path/to/a/file   linkname

Sau đó, có ba cách để thay đổi liên kết tượng trưng:

  • Sử dụng ln với -flực lượng và thậm chí cho các thư mục -n(inode có thể được sử dụng lại):

    ln -sfn /some/new/path linkname
    
  • Xóa symlink và tạo một liên kết mới (ngay cả đối với các thư mục):

    rm linkname; ln -s /some/new/path linkname
    
  • tạo một liên kết tượng trưng mới, sau đó mvnó (thay đổi nguyên tử ngay cả đối với các thư mục):

    ln -s  /some/new/path newlinkname
    mv -fT newlinkname linkname             # linkname remains after the command
    
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.