Tôi không nghĩ có một tiện ích như vậy. Với GNU readlink
, bạn có thể làm một cái gì đó như:
is_in() (
needle=$(readlink -ve -- "$1" && echo .) || exit
haystack=$(readlink -ve -- "$2" && echo .) || exit
needle=${needle%??} haystack=${haystack%??}
haystack=${haystack%/} needle=${needle%/}
case $needle in
("$haystack" | "$haystack"/*) true;;
(*) false;;
esac
)
Điều đó giải quyết tất cả các liên kết tượng trưng để kết thúc với một đường dẫn tuyệt đối chính tắc cho cả kim và haystack.
Giải trình
- Chúng ta có được đường dẫn tuyệt đối chính tắc của cả kim và cỏ khô . Chúng tôi sử dụng
-e
thay vì -f
như chúng tôi muốn đảm bảo các tập tin tồn tại. Các -v
tùy chọn đưa ra một thông báo lỗi nếu các tập tin không thể truy cập.
- Như mọi khi,
--
nên được sử dụng để đánh dấu sự kết thúc của các tùy chọn và trích dẫn vì chúng tôi không muốn gọi toán tử split + global ở đây.
- Thay thế lệnh trong các shell giống như Bourne có một lỗi không phù hợp ở chỗ nó loại bỏ tất cả các ký tự dòng mới khỏi đầu ra của một lệnh, không chỉ là một lệnh được thêm bởi các lệnh để kết thúc dòng cuối cùng. Điều đó có nghĩa là đối với một tệp như thế
/foo<LF><LF>
, $(readlink -ve -- "$1")
sẽ trả về /foo
. Các công việc xung quanh chung cho rằng là để nối thêm một nhân vật phi LF (ở đây .
) và dải đó và nhân vật LF phụ thêm bởi readlink
với var=${var%??}
(loại bỏ hai ký tự cuối cùng).
Cây kim được coi là nằm trong đống cỏ khô nếu đó là đống cỏ khô hoặc nếu đó là đống cỏ khô / thứ gì đó. Tuy nhiên, điều đó sẽ không hoạt động nếu haystack là /
( /etc
thay vào đó là không //something
). /
thường cần được xử lý đặc biệt bởi vì trong khi /
và /xx
có cùng số lượng dấu gạch chéo, thì một mức này cao hơn mức khác.
Một cách để giải quyết nó là để thay thế /
với chuỗi rỗng mà được thực hiện với var=${var%/}
(con đường duy nhất kết thúc với /
đó readlink -e
là /
, vì vậy việc xoá dấu /
được thay đổi /
để chuỗi rỗng).
Để chuẩn hóa đường dẫn tệp, bạn có thể sử dụng chức năng trợ giúp.
canonicalize_path() {
# canonicalize paths stored in supplied variables. `/` is returned as
# the empty string.
for _var do
eval '
'"$_var"'=$(readlink -ve -- "${'"$_var"'}" && echo .) &&
'"$_var"'=${'"$_var"'%??} &&
'"$_var"'=${'"$_var"'%/}' || return
done
}
is_in() (
needle=$1 haystack=$2
canonicalize_path needle haystack || exit
case $needle in
("$haystack" | "$haystack"/*) true;;
(*) false;;
esac
)
fie.txt
hoặcfum
chính nó là một liên kết tượng trưng bên ngoàifoo
?