Cho ví dụ này:
mkdir a
ln -s a b
ln -s b c
ln -s c d
Nếu tôi thực thi:
ls -l d
Nó sẽ hiển thị:
d -> c
Có cách nào để ls
hoặc bất kỳ lệnh linux nào khác hiển thị d -> c -> b -> a
thay thế?
Cho ví dụ này:
mkdir a
ln -s a b
ln -s b c
ln -s c d
Nếu tôi thực thi:
ls -l d
Nó sẽ hiển thị:
d -> c
Có cách nào để ls
hoặc bất kỳ lệnh linux nào khác hiển thị d -> c -> b -> a
thay thế?
Câu trả lời:
Chỉ cần sử dụng namei
:
$ namei d
f: d
l d -> c
l c -> b
l b -> a
d a
ls
. Cảm ơn!
readlink -e <link>
đường dẫn đọc [TÙY CHỌN] ... TẬP TIN
- -e, --canonicalize-
canonicalize bằng cách theo mọi symlink trong mọi thành phần của tên đã cho theo cách đệ quy, tất cả các thành phần phải tồn tại
$ mkdir testlink
$ cd testlink
pjb@pjb-desktop:~/testlink$ ln -s c b
pjb@pjb-desktop:~/testlink$ ln -s b a
pjb@pjb-desktop:~/testlink$ ls -l
total 0
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 a -> b
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 b -> c
pjb@pjb-desktop:~/testlink$ echo foo > c
pjb@pjb-desktop:~/testlink$ cat a
foo
pjb@pjb-desktop:~/testlink$ readlink -e a
/home/pjb/testlink/c
lưu ý: readlink a tự trả về b
lưu ý số 2: cùng với find -l, một tiện ích để liệt kê các chuỗi có thể dễ dàng được viết bằng perl, nhưng cũng phải đủ thông minh để phát hiện các vòng lặp
readlink sẽ không xuất bất cứ thứ gì nếu bạn có một vòng lặp. Điều này tốt hơn là bị mắc kẹt, tôi cho rằng.
pjb@pjb-desktop:~/testlink$ ln -sf a c
pjb@pjb-desktop:~/testlink$ ls -l
total 0
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 a -> b
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 b -> c
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 09:03 c -> a
pjb@pjb-desktop:~/testlink$ readlink -e a
pjb@pjb-desktop:~/testlink$ # (note: no output)
brew install coreutils
vàgreadlink -e <link>
Đây là một hàm đệ quy trong Bash:
chain() { export chain; local link target; if [[ -z $chain ]]; then chain="$1"; fi; link=$(stat --printf=%N $1); while [[ $link =~ \-\> ]]; do target="${link##*\`}"; target="${target%\'}"; chain+=" -> $target"; chain "$target"; return; done; echo "$chain"; unset chain; }
Trên nhiều dòng:
chain() {
export chain
local link target
if [[ -z $chain ]]
then
chain="$1"
fi
link=$(stat --printf=%N "$1")
while [[ $link =~ \-\> ]]
do
target="${link##*\`}"
target="${target%\'}"
chain+=" -> $target"
if [[ ! $target =~ / && $1 =~ / ]]
then
target="${1%/*}/$target"
fi
chain "$target"
return
done
echo "$chain"
unset chain
}
Ví dụ:
$ chain d
d -> c -> b -> a
$ chain c
c -> b -> a
$ chain a
a
Nó đòi hỏi stat(1)
có thể không có mặt trên một số hệ thống.
Nó sẽ thất bại nếu tên chứa backticks, dấu ngoặc đơn hoặc "->". Nó bị mắc kẹt trong một vòng lặp với các vòng lặp symlink (điều này có thể được giải quyết bằng cách sử dụng một mảng kết hợp trong Bash 4). Nó xuất một biến gọi là "chuỗi" mà không cần quan tâm đến việc nó đã được sử dụng chưa.
Có thể có những vấn đề khác với nó.
Chỉnh sửa:
Đã sửa lỗi với một số liên kết tương đối. Một số vẫn không hoạt động, nhưng phiên bản dưới đây không yêu cầu mục tiêu của liên kết tồn tại.
Đã thêm phiên bản sử dụng đường dẫn đọc:
chain ()
{
export chain;
local target;
if [[ -z $chain ]]; then
chain="$1";
fi;
target=$(readlink "$1");
while [[ $target ]]; do
chain+=" -> $target";
if [[ ! $target =~ / && $1 =~ / ]]
then
target="${1%/*}/$target"
fi
chain "$target";
return;
done;
echo "$chain";
unset chain
}
readlink
dường như không cho thấy điều đó. Java trên Ubuntu là:/usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java