Làm thế nào tôi có thể biết nếu hai tập tin được liên kết cứng từ dòng lệnh? ví dụ: một cái gì đó liên kết này:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
Làm thế nào tôi có thể biết nếu hai tập tin được liên kết cứng từ dòng lệnh? ví dụ: một cái gì đó liên kết này:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
Câu trả lời:
Trên hầu hết các hệ thống tệp¹, một tệp được xác định duy nhất bởi số inode của nó , vì vậy tất cả những gì bạn cần kiểm tra là liệu hai tệp có cùng số inode và nằm trên cùng một hệ thống tệp không.
Ash, ksh, bash và zsh có cấu trúc kiểm tra cho bạn: toán tử đẳng thức tập tin -ef
.
[ fileA -ef fileB ] && ! [ fileA -ef fileC ]
Đối với các trường hợp nâng cao hơn, hãy ls -i /path/to/file
liệt kê số inode của tệp. df -P /path/to/file
hiển thị hệ thống tập tin nào tập tin được bật (nếu hai tập tin nằm trong cùng một thư mục, chúng nằm trên cùng một hệ thống tập tin). Nếu hệ thống của bạn có stat
lệnh, nó có thể hiển thị số inode và số hệ thống tập tin ( stat
thay đổi tùy theo hệ thống, kiểm tra tài liệu của bạn). Nếu bạn muốn xem nhanh các liên kết cứng trong một thư mục, hãy thử ls -i | sort
(có thể chuyển sang awk ).
¹ Tất cả các hệ thống tập tin bản địa unix, và vài người khác như NTFS, nhưng trường hợp có thể không kỳ lạ như CramFS.
fileA -ef fileB
cũng trả về 0
(thành công) nếu fileA
là một liên kết tượng trưng fileB
hoặc ngược lại hoặc cả hai đều liên kết đến cùng một tệp.
[ .bashrc -ef .bash/.bashrc ]
là chính xác. Dĩ nhiên, không có ngữ cảnh, tôi không biết tại sao nó lại không thực sự hoạt động. Bạn có thể so sánh các tệp sai, bạn không thể kiểm tra kết quả chính xác, bạn có thể sử dụng shell mà không -ef
, ...
[
và là một từ đồng nghĩa của test
. Nhưng man [
hoặc man test
sẽ cung cấp cho bạn trang man của lệnh bên ngoài, trong khi mọi vỏ ngoài đều có lệnh tích hợp với các tùy chọn hơi khác nhau, vì vậy bạn cần tìm kiếm cái này trong hướng dẫn sử dụng của vỏ.
function is-hardlinked() {
r=yes
[ "`stat -c '%i' $1`" != "`stat -c '%i' $2`" ] && r=no
echo $r
}
stat -c %d
). Và nếu bạn đang dùng Linux (được cung cấp stat
lệnh của bạn ), trình bao của bạn có [ fileA -ef fileB ]
thể thực hiện trực tiếp tất cả điều này. Ngoài ra, lệnh của bạn ngắt một cách miễn phí với các tên tệp chứa khoảng trắng hoặc \[?*
, hoặc bắt đầu bằng -
: luôn đặt dấu ngoặc kép xung quanh lệnh susbtitutions ( "$(stat -c %i -- "$1")"
).
function
từ khóa không di động có tên hàm (trên tài khoản chứa dấu gạch ngang) vi phạm các quy ước POSIX trên các tên được phép?
$1
và $2
. Bạn cũng có thể muốn sử dụng $()
cú pháp thay vì backticks vì dấu ngoặc làm rõ nơi lệnh bắt đầu và nơi kết thúc và việc lồng nhau đơn giản hơn.
Như poster đầu tiên đề xuất, bạn có thể viết một kịch bản dựa trên cái gì đó như thế này trên Linux:
stat -c '%i' fileA fileB fileC
stat -c %d
). Và nếu bạn đang dùng Linux (được cung cấp stat
lệnh của bạn ), trình bao của bạn có [ fileA -ef fileB ]
thể thực hiện trực tiếp tất cả điều này.
Với GNU find(1)
phiên bản 4.2.11 trở lên, bạn cũng có thể sử dụng điều này:
if [ "yes" = "$(find fileA -samefile fileB -exec echo yes \;)" ]; then
echo yes
else
echo no
fi
Nếu fileA
cùng một tệp như fileB
sau đó find
sẽ in "có" và điều kiện trở thành đúng.
Ngược lại với việc sử dụng toán tử đẳng thức tập tin, điều -ef
này sẽ tạo ra một quy trình mới.