Ví dụ: kiểm tra nếu $PWD
là thư mục con của / home. Nói cách khác, tôi đang tìm kiếm một hoạt động chuỗi bash để kiểm tra xem một chuỗi có bắt đầu bằng chuỗi khác không.
Ví dụ: kiểm tra nếu $PWD
là thư mục con của / home. Nói cách khác, tôi đang tìm kiếm một hoạt động chuỗi bash để kiểm tra xem một chuỗi có bắt đầu bằng chuỗi khác không.
Câu trả lời:
Nếu bạn muốn kiểm tra một cách đáng tin cậy liệu một thư mục có phải là thư mục con của thư mục khác hay không, bạn sẽ cần nhiều hơn chỉ là kiểm tra tiền tố chuỗi. Câu trả lời của Gilles mô tả chi tiết cách thực hiện bài kiểm tra này đúng cách.
Nhưng nếu bạn muốn kiểm tra tiền tố chuỗi đơn giản (có thể bạn đã bình thường hóa đường dẫn của mình?), Đây là một cách tốt:
test "${PWD##/home/}" != "${PWD}"
Nếu $PWD
bắt đầu bằng "/ home /", nó sẽ bị xóa ở bên trái, điều đó có nghĩa là nó sẽ không khớp với bên phải, vì vậy "! =" Trả về đúng.
${PWD/#$HOME/\~}
"${PWD%%/subdir*}"
để phát hiện xem người dùng hiện đang ở subdir
hoặc trong thư mục con của subdir
, vì %% bắt giữ từ cuối chuỗi thay vì bắt đầu. Điều này sẽ hữu ích cho bất kỳ ai đang tìm kiếm thêm thông tin về việc thay thế tham số: tldp.org/LDP/abs/html/parameter-substlation.html
Để kiểm tra xem một chuỗi có phải là tiền tố của chuỗi khác hay không, trong bất kỳ shell kiểu Bourne nào:
case $PWD/ in
/home/*) echo "home sweet home";;
*) echo "away from home";;
esac
Nguyên tắc tương tự làm việc cho một bài kiểm tra hậu tố hoặc chuỗi con. Lưu ý rằng trong các case
cấu trúc, không giống như trong tên tệp, *
khớp với bất kỳ ký tự nào, kể cả ký tự /
đầu tiên .
.
Trong các shell thực hiện [[ … ]]
cú pháp (ví dụ bash, ksh và zsh), nó có thể được sử dụng để khớp một chuỗi với một mẫu. (Lưu ý rằng [
lệnh chỉ có thể kiểm tra các chuỗi cho đẳng thức.)
if [[ $PWD/ = /home/* ]]; then …
Nếu bạn đang kiểm tra cụ thể liệu thư mục hiện tại có ở bên dưới hay không /home
, thì kiểm tra chuỗi con đơn giản là không đủ, vì các liên kết tượng trưng.
Nếu /home
là một hệ thống tệp của riêng nó, hãy kiểm tra xem thư mục hiện tại ( .
) có nằm trong hệ thống tệp đó không.
if [ "$(df -P . | awk 'NR==2 {print $6}')" = "/home" ]; then
echo 'The current directory is on the /home filesystem'
fi
Nếu bạn có NetBSD, OpenBSD hoặc GNU (tức là Linux) readlink
, bạn có thể sử dụng readlink -f
để loại bỏ các liên kết tượng trưng từ một đường dẫn.
case $(readlink -f .)/ in $(readlink -f /home)/*) …
Nếu không, bạn có thể sử dụng pwd
để hiển thị thư mục hiện tại. Nhưng bạn phải cẩn thận không sử dụng shell được tích hợp nếu shell của bạn theo dõi cd
các lệnh và giữ tên bạn đã sử dụng để truy cập vào thư mục thay vì vị trí thực tế của nó.
case $(pwd -P 2>/dev/null || env PWD= pwd)/ in
"$(cd /home && { pwd -P 2>/dev/null || env PWD= pwd; })"/*) …
Phiên bản thô:
[ ${PWD:0:6} = "/home/" ]
Có nhược điểm là người ta phải đếm các ký tự trước và người ta không thể thay thế /home/
bằng một cái gì đó chung chung như thế nào $1
.
chỉnh sửa (cảm ơn @Michael) để tổng quát hóa để so sánh với $VAR
người ta có thể sử dụng
[ "${PWD:0:${#VAR}}" = $VAR ]
${#var}
là độ dài của $var
, vì vậy bạn có thể khái quát nó thành[ "${PWD:0:${#1}}" = "$1" ]
Tôi không hiểu câu hỏi quá rõ, nhưng để tìm cha mẹ của $ PWD , hãy làm dirname $PWD
. Để tìm cha mẹ của cha mẹ, hãy chạy dirname $(dirname $PWD)
, v.v.
/
. Ok, tôi có thể kiểm tra đệ quy, nhưng không có gì dễ dàng hơn?
Sử dụng awk
:
echo $PWD | awk -v h="/home" '$0 ~ h {print "MATCH"}'
Hừm, thật đáng tiếc khi [
không có tùy chọn STRING1 starts with STRING2
điều kiện thử nghiệm .
Bạn có thể thử echo $PWD | grep '^$VAR'
, nhưng nó có thể thất bại theo những cách thú vị khi VAR
chứa các biểu tượng đặc biệt.
awk
's index
chức năng nên có thể làm các trick. Nhưng tất cả điều này dường như quá nặng đối với một điều dễ dàng như vậy để kiểm tra.
Nếu phần tìm kiếm của đường dẫn được tìm thấy, tôi "làm trống" biến:
[[ -z "${PWD//*\/home\/*/}" ]] && echo "toto"
[ "${PWD##$VAR}" != "$PWD" ]
Và nếu đây là [code-golf] ( stackoverflow.com/questions/tagged/code-golf)question bạn đã đánh bại tôi bằng hai ký tự ;-) Ngoài ra, nó có vẻ dễ đọc hơn ...