tìm tất cả các liên kết tượng trưng trong cây thư mục chỉ ra bên ngoài cây đó


8

Tôi thường xuyên di chuyển cây thư mục đến các vị trí khác hoặc sao chép tarball của chúng sang các máy khác và tôi muốn có một phương pháp để kiểm tra xem có bất kỳ liên kết tượng trưng nào trong cây thư mục A trỏ đến các vị trí bên ngoài A không vì chúng sẽ bị phá vỡ khi di chuyển / sao chép danh mục.

Câu trả lời:


7

Bạn muốn một chương trình được gọi realpath, được sử dụng cùng với find.

Ví dụ:

find . -type l -exec realpath {} \; | grep -v "^$(pwd)"

1
Câu thần chú bạn cung cấp chỉ báo cáo vị trí mục tiêu vi phạm, không phải là liên kết tượng trưng chỉ đến nó. Như vậy tôi đã loại bỏ sự chấp nhận của tôi. Vui lòng xem "câu trả lời" của tôi bên dưới: unix.stackexchange.com/a/308899/24044 và nếu bạn hài lòng với nó (hoặc cải thiện nó) tôi sẽ xóa "câu trả lời" của mình và chấp nhận lại câu hỏi của bạn.
Marcus Junius Brutus

2

Sử dụng bindfs để tạo một khung nhìn khác của cây thư mục đó.

mkdir /tmp/view
bindfs /some/directory /tmp/view

Sau đó, sử dụng tiện ích symlink (được phân phối bởi nhiều bản phân phối hoặc biên dịch nó từ nguồn ) để phát hiện các liên kết hệ thống tập tin chéo.

symlinks -r /tmp/view | sed -n 's/^\(absolute\|other_fs\): //p'

(Lưu ý rằng phân tích cú pháp đầu ra giả định rằng các liên kết tượng trưng của bạn và các mục tiêu của chúng không chứa các dòng mới, cũng như các đường dẫn đến các liên kết tượng trưng có chứa chuỗi con  -> .) Tiện ích tương tự cũng có thể chuyển đổi các liên kết tuyệt đối thành tương đối (nhưng bạn muốn làm điều đó từ vị trí ban đầu).


2

Với zsh:

cd -P -- "$dir"
for i (**/*([email protected])) [[ $i:A = $PWD/* ]] || [[ $i:A = $PWD ]] || print -r -- "$i => $i:A"

Bây giờ, nếu thư mục là /foovà bạn có /foo/barmột liên kết tượng trưng /foo/baz, đó là một liên kết có mục tiêu nằm trong / foo, nhưng một khi đã di chuyển, liên kết vẫn sẽ bị phá vỡ, do đó bạn cũng có thể muốn khớp các liên kết tượng trưng với các đường dẫn tuyệt đối.

Nhưng ngay cả khi đó, một bar => ../foo/baztrong /foosẽ là một vấn đề (âm tính giả), do đó, một a => bnơi blà một liên kết tượng trưng bên ngoài cây (dương tính giả, tùy thuộc vào cách bạn muốn xem xét nó)


2

Tôi đã phải điều chỉnh một chút câu trả lời được đưa ra bởi @bahamat để làm cho nó hoạt động.

Phiên bản được cung cấp chỉ đơn giản là báo cáo vị trí tuyệt đối vi phạm nhưng không phải là liên kết tượng trưng cho nó.

Đây là những gì tôi đã sử dụng (tôi chắc chắn rằng nó có thể được cải thiện):

for f in $(find . -type l ); do echo -n $(realpath $f) && echo -n "|" && echo $f ; done | grep -v "^$(pwd)" | cut -d \| -f 2 

Tôi thấy đây là kịch bản hữu ích nhất: for f in $(find . -type l); do echo $(realpath -m -q $f) '<-' $f; done | grep-v "^$(pwd)"(đáng chú ý nhất -m-qlọc ra các liên kết bị hỏng và không bên ngoài)
Adam Lindberg

1

GNU coreutils chứng minh realpath, giải quyết các liên kết tượng trưng. Với điều này, bạn có thể so sánh từng mục tiêu của symlink với thư mục làm việc hiện tại với một cái gì đó như:

#!/bin/bash

find . | while read filename
do
  if realpath $filename | grep -E "^$PWD" > /dev/null
  then
    echo 'this file is safe'
  else
    echo 'this file links externally'
  fi
done

Một số vấn đề: không -type l, không có -rtùy chọn nào read, IFS không được vệ sinh read, $filenamekhông được trích dẫn, $PWDđược coi là biểu thức chính quy, các đường dẫn có ký tự dòng mới không được tính, /foobarsẽ được khớp với $PWD== "/ foo"
Stéphane Chazelas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.