查找 inode 号的便携式方法

查找 inode 号的便携式方法

起初我用stat -c %i file(来帮助检测监狱的存在),它似乎可以在任何 Linux 发行版上运行。在 OS X 上我必须使用ls -i file | cut -d ' ' -f 1.

有没有某种方法可以在 shell 脚本中查找文件的索引节点号,该脚本可以跨 *nix 平台移植并且不依赖于臭名昭著的反复无常ls

答案1

可能的解决方案:POSIX 规范ls指定-i,所以也许它是可移植的。有谁知道一个流行的ls实现不是支持这一点,或者以与以下示例不同的方式打印它:

$ ls -di /
2 /

答案2

这应该是可移植的,并且可以处理包含空格、换行符或其他奇怪字符的文件名出了名的反复无常ls的行为。

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

答案3

为了提高可移植性,您还可以围绕命令实现特定于平台的包装函数(此处称为statinode()stat,该函数可以基于uname -s(请参阅乌纳梅)。

ls仅需要作为后备选项。

(
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
)

答案4

另一个解决方案:

#!/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";

您可以放心地假设 Perl 已安装。

相关内容