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 $1là 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ì $1là 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 1nếu tập tin được chỉ định bởi $1bất cứ nơi nào khác ngoài thư mục /home/charlesingalls/. realpathchuẩ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.
realpathyê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ụ: -qtù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
readlinkcũ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 readlinkcó 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.