Câu trả lời:
Sử dụng -f
cờ để in phiên bản chuẩn. Ví dụ:
readlink -f /root/Public/myothertextfile.txt
Từ man readlink
:
-f, --canonicalize
canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
brew install coreutils
. Điều này cài đặt các phiên bản gnu cơ bản của các lệnh có tiền tố với chữ cái g
, tức làgreadlink -f somefile
Ubuntu 18.04.1 LTS (Bionic Beaver)
các trang của readlink có một ghi chú cho biết "Note realpath (1) là lệnh ưa thích để sử dụng cho chức năng chuẩn hóa."
readlink là lệnh bạn muốn. Bạn nên nhìn vào trang man cho lệnh. Bởi vì nếu bạn muốn theo một chuỗi các liên kết tượng trưng đến tệp thực tế, thì bạn cần chuyển đổi -e hoặc -f:
$ ln -s foooooo zipzip # fooooo doesn't actually exist
$ ln -s zipzip zapzap
$ # Follows it, but doesn't let you know the file doesn't actually exist
$ readlink -f zapzap
/home/kbrandt/scrap/foooooo
$ # Follows it, but file not there
$ readlink -e zapzap
$ # Follows it, but just to the next symlink
$ readlink zapzap
zipzip
Điều này cũng sẽ làm việc:
ls -l /root/Public/myothertextfile.txt
nhưng readlink
sẽ được ưu tiên sử dụng trong tập lệnh hơn là phân tích cú pháp ls
.
Nếu bạn muốn hiển thị nguồn và đích của liên kết, hãy thử stat -c%N files*
. Ví dụ
$ stat -c%N /dev/fd/*
‘/dev/fd/0’ -> ‘/dev/pts/4’
‘/dev/fd/1’ -> ‘/dev/pts/4’
Nó không tốt cho việc phân tích cú pháp (sử dụng readlink
cho điều đó), nhưng nó hiển thị tên liên kết và đích, mà không có sự lộn xộn củals -l
-c
có thể được viết --format
và %N
có nghĩa là tên tập tin được trích dẫn với sự bổ nhiệm nếu liên kết tượng trưng.
Đây readlink
là một điều tốt, nhưng cụ thể là GNU và không đa nền tảng. Tôi đã từng viết các kịch bản đa nền tảng cho /bin/sh
, do đó tôi sẽ sử dụng một cái gì đó như:
ls -l /root/Public/myothertextfile.txt | awk '{print $NF}'
hoặc là:
ls -l /root/Public/myothertextfile.txt | awk -F"-> " '{print $2}'
nhưng những điều này cần phải được thử nghiệm trên các nền tảng khác nhau. Tôi nghĩ rằng chúng sẽ hoạt động, nhưng không chắc chắn 100% cho ls
định dạng đầu ra.
Kết quả ls
cũng có thể được phân tích cú pháp bên trong bash
mà không phụ thuộc vào một lệnh bên ngoài như awk
, sed
hoặc perl
.
bash_realpath
Hàm này , giải quyết đích cuối cùng của một liên kết (liên kết → liên kết → liên kết → cuối cùng):
bash_realpath() {
# print the resolved path
# @params
# 1: the path to resolve
# @return
# >&1: the resolved link path
local path="${1}"
while [[ -L ${path} && "$(ls -l "${path}")" =~ -\>\ (.*) ]]
do
path="${BASH_REMATCH[1]}"
done
echo "${path}"
}
Nếu bạn không thể sử dụng readlink
, thì việc phân tích kết quả ls -l
có thể được thực hiện như thế này.
Kết quả bình thường sẽ là:
ls -l /root/Public/myothertextfile.txt
lrwxrwxrwx 1 root root 30 Jan 1 12:00 /root/Public/myothertextfile.txt -> /root/Public/mytextfile.txt
Vì vậy, chúng tôi muốn thay thế mọi thứ trước "->" và bao gồm mũi tên. Chúng ta có thể sử dụng sed
cho việc này:
ls -l /root/Public/myothertextfile.txt | sed 's/^.* -> //'
/root/Public/mytextfile.txt
Câu hỏi không đủ chính xác để đưa ra một câu trả lời đơn giản như một trong những câu brian-brazil:
readlink -f some_path
thực sự sẽ hủy bỏ mọi liên kết tượng trưng liên quan đến việc xây dựng đường dẫn đến mục tiêu cuối cùng phía sau some_path
.
Nhưng một cấp độ của các liên kết xếp tầng chỉ là một trường hợp cụ thể trong số các liên kết khác trong một hệ thống, trường hợp chung là N cấp của các liên kết xếp tầng. Nhìn vào những điều sau đây trên hệ thống của tôi:
$ rwhich emacs
/usr/bin/emacs
/etc/alternatives/emacs
/usr/bin/emacs24-x
rwhich
là việc thực hiện đệ quy của riêng tôi về which
việc in tất cả các liên kết xếp tầng trung gian (đến stderr) xuống mục tiêu cuối cùng (tới thiết bị xuất chuẩn).
Sau đó, nếu tôi muốn biết những gì là:
mục tiêu của symlink / usr / bin / emacs **, câu trả lời rõ ràng với tôi là được /etc/alternatives/emacs
trả về bởi:
readlink $(which emacs)
readlink /usr/bin/emacs
các thức mục tiêu đằng sau tầng symlink / usr / bin / emacs, câu trả lời sẽ được /usr/bin/emacs24-x
như trả về bởi:
readlink -f $(which emacs)
readlink -f /usr/bin/emacs
rwhich emacs 2>/dev/null
Nếu bạn tìm thấy mục tiêu của tất cả các liên kết trong một thư mục và thư mục con của nó, hãy sử dụng find . -type l -ls
lệnh với loại liên kết như sau:
me@local.localdomain:~/test$ find . -type l -ls
8601855888 0 lrwxr-xr-x 1 me staff 6 Jan 24 19:53 ./link -> target
Nếu bạn muốn mục tiêu của một đơn, thì ls -l
nên hoạt động:
me@local.localdomain:~/test$ ls -l
total 0
lrwxr-xr-x 1 me staff 6 Jan 24 19:53 link -> target
-rw-r--r-- 1 me staff 0 Jan 24 19:53 target
readlink -f
.