Cách di động để tìm số inode


10

Lúc đầu, tôi đã sử dụng stat -c %i file(để giúp phát hiện sự hiện diện của nhà tù ), dường như hoạt động trên bất kỳ bản phân phối Linux nào dưới ánh mặt trời. Trên OS X 'tôi phải sử dụng ls -i file | cut -d ' ' -f 1.

Có cách nào để tìm số inode của tệp trong tập lệnh shell có khả năng di động trên các nền tảng * nix và không phụ thuộc vào mức độ khét tiếng không ls?



Bạn có thể nói rõ hơn về "ls khét tiếng khét tiếng" không?
jlliagre

@jlliagre: Những người khác đã làm điều đó tốt hơn rồi.
l0b0

Được rồi, đối với các tập tin như vậy, xem trả lời của tôi.
jlliagre

Câu trả lời:


11

Giải pháp có thể: Thông số POSIX đểls chỉ định -i, vì vậy có thể đó là di động. Có ai biết một thực hiện phổ biến của lskhông hỗ trợ điều này, hoặc in nó theo một cách khác nhau từ các ví dụ sau:

$ ls -di /
2 /

3
@jlliagre: Vui lòng đọc trước khi đăng. Các statlệnh đã không làm việc trên OS X, ls -dilàm việc trên cả hai.
l0b0

1
Ngay cả Busybox lscũng có -d-ilà các tính năng bắt buộc (mặc dù lsbản thân nó là tùy chọn, giống như mọi thứ khác).
Gilles 'SO- ngừng trở nên xấu xa'

1
Michael hiểu lầm chính xác là những gì tôi đã nhận xét. Nó không có giá trị một bình luận "đọc trước khi đăng" khá thô lỗ và không xứng đáng.
jlliagre

2
một số trường hợp ngoại lệ: lsvới -icác miếng đệm phía trước có khoảng trắng trên ít nhất Solaris 10 (có thể là Solaris 11, tôi chưa kiểm tra). Có vẻ như đây là hành vi truyền thống quay trở lại phiên bản Unix 7, vì vậy tôi nghi ngờ rất nhiều hương vị * nix của công ty đã giữ hành vi này (mặc dù tôi chỉ có Solaris 10 trên tay). Vì vậy, gần như tôi có thể nói, nếu bạn sử dụng một cái gì đó mô tả đúng các trường trong khoảng trắng tùy ý (vì vậy, không cut, nhưng ví dụ awkhoặc chỉ tách trường của vỏ), nó có thể di chuyển để dự đoán chuỗi không phải khoảng trắng đầu tiên là inode con số.
mtraceur

1
@ l0b0 Vâng. Nó đòi hỏi sự cống hiến khổ dâm: một loạt các nghiên cứu / thử nghiệm và ghi nhớ cho lợi nhuận liên tục giảm dần. Có thể, ít nhất là đối với một số định nghĩa về "di động", nhưng đó không phải là một trải nghiệm thú vị.
mtraceur

2

Điều này nên có thể di động và làm việc với các tên tệp có chứa khoảng trắng, dòng mới hoặc các ký tự kỳ lạ khác dẫn đến hành vi ls khét tiếng khét tiếng .

filename="whatever file name"
find . -name "$filename" -exec sh -c 'ls -di "$0" | head -1' {} \;

1

Để tăng tính di động, bạn cũng có thể triển khai chức năng trình bao bọc dành riêng cho nền tảng (được gọi là statinode()) xung quanh statlệnh có thể dựa trên đầu ra của uname -s(xem uname ).

ls sẽ chỉ cần là một tùy chọn dự phòng.

(
shopt -s nocasematch nullglob    # using Bash
case "$(uname -s)" in
   # nocasematch alternative
   #[Ll][Ii][Ni][Uu][Xx]   )  statinode() { stat -c '%i' "$@"; return 0; };;
   "Linux"   )      statinode() { stat -c '%i' "$@"; return 0; };;
   "Darwin"  )      statinode() { stat -f '%i' "$@"; return 0; };;
   "FreeBSD" )      statinode() { stat -f '%i' "$@"; return 0; };;
           * )      statinode() { ls -id "$@" | cut -d ' ' -f 1; return 0; };;
esac
#export -f statinode
statinode / / / /
shopt -u nocasematch nullglob
)

0

statlà một phần của gói GNU Coreutils . OSX sử dụng một stattriển khai khác (có lẽ là dựa trên BSD) không có cùng đối số dòng lệnh.

Bạn luôn có thể cài đặt GNU Coreutils trên OSX. Tất nhiên điều đó không có ích nếu bạn cần một giải pháp hoạt động trên các hệ thống OSX không có GNU Coreutils.

Hoặc, nếu tôi đang đọc chính xác trang hướng dẫn OSX (1) , stat -f %i filetrên OSX hoạt động giống như stat -c %i filesử dụng phiên bản Coreutils. (Xác định phiên bản statnào bạn có là một vấn đề khác; bạn có thể thử stat --version >/dev/null; nếu thành công, bạn có phiên bản GNU Coreutils.)

Các ls -digiải pháp là di động hơn và ít rắc rối, nhưng đây là một sự thay thế.


0

Giải pháp khác:

#!/usr/bin/perl

use strict;
use warnings;

die "Usage: $0 filename\n" if scalar @ARGV != 1;
my $file = $ARGV[0];
my @stat = stat $file;
die "$file: $!\n" if not @stat;
print "$stat[1]\n";

Bạn có thể có thể giả định rằng Perl đã được cài đặt một cách an toàn.


0

Tương tự như cách tiếp cận của jeff, statcũng có thể được kiểm tra trực tiếp.

(
if (stat -c '%i' / 1>/dev/null 2>&1; exit $?); then
   statinode() { stat -c '%i' "$@"; return 0; }
elif (stat -f '%i' / 1>/dev/null 2>&1; exit $?); then
   statinode() { stat -f '%i' "$@"; return 0; }
elif test -n "$(exec 2>/dev/null; ls -id / | cut -d ' ' -f 1)"; then
   statinode() { ls -id "$@" | cut -d ' ' -f 1; return 0; }
else
   echo 'Could not create statinode(). Exiting ...' && exit 1
fi
# export -f statinode
statinode / / / /
declare -f statinode
)
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.