Câu trả lời này giả định rằng $1
được phép bao gồm các thư mục con. Nếu bạn quan tâm đến trường hợp đơn giản hơn $1
là tên thư mục đơn giản, thì hãy xem một trong những câu trả lời khác.
Ký tự đại diện không được mở rộng khi trong dấu ngoặc kép. Vì $1
là trong dấu ngoặc kép, ký tự đại diện không phải là vấn đề.
Cả hai ../
và liên kết tượng trưng có thể che khuất vị trí thực sự của một tập tin. Dưới đây là các thử nghiệm để xác định xem tập tin có thực sự, không chỉ là dường như, theo con đường chúng ta muốn.
Hệ thống mới hơn: sử dụng realpath
Đối với việc tìm hiểu xem tập tin có thực sự nếu tập tin thực sự nằm dưới /home/charlesingalls/
hay không, bạn có thể sử dụng realpath
:
realpath --relative-base=/home/charlesingalls/ "/home/charlesingalls/$1" | grep -q '^/' && exit 1
Ở trên chạy exit 1
nếu tập tin được chỉ định bởi $1
bất cứ nơi nào khác ngoài thư mục /home/charlesingalls/
. realpath
chuẩn hóa toàn bộ đường dẫn, loại bỏ cả symlink và ../
.
realpath
là một phần của lõi GNU và nên có sẵn trên bất kỳ hệ thống Linux nào.
realpath
yêu cầu GNU coreutils 8.15 (tháng 1 năm 2012) hoặc tốt hơn .
Ví dụ
Để giải thích cách realpath theo sau ../
để xác định vị trí thực của tệp (ví dụ: -q
tùy chọn grep được bỏ qua để hiển thị đầu ra thực tế của grep):
$ touch /tmp/test
$ realpath --relative-base=$HOME "$HOME/../../tmp/test" | grep '^/' && echo FAIL
/tmp/test
FAIL
Để chứng minh làm thế nào nó theo symlink:
$ ln -s /tmp/test ~/test
$ realpath --relative-base=$HOME "$HOME/test" | grep '^/' && echo FAIL
/tmp/test
FAIL
Hệ thống cũ hơn: sử dụng readlink -e
readlink
cũng có khả năng cấu hình hóa một đường dẫn, theo cả hai liên kết tượng trưng và ../
:
readlink -e "$HOME/test" | grep -q "^$HOME" || exit 1
Sử dụng cùng một tệp ví dụ:
$ readlink -e "$HOME/../../tmp/test" | grep "$HOME" || echo FAIL
FAIL
$ readlink -e "$HOME/test" | grep "^$HOME" || echo FAIL
FAIL
Ngoài việc có sẵn trên các hệ thống GNU cũ hơn, các phiên bản readlink
có sẵn trên BSD.
/
. Ký tự đại diện không được giải thích bên trong dấu ngoặc kép.