最初,我使用stat -c %i file
(以帮助检测是否存在监牢),它似乎可以在阳光下的任何Linux发行版上运行。在OS X上,我必须使用ls -i file | cut -d ' ' -f 1
。
是否有某种方法可以在可跨* nix平台移植且不依赖于反复无常的shell脚本中查找文件的inode编号ls
?
最初,我使用stat -c %i file
(以帮助检测是否存在监牢),它似乎可以在阳光下的任何Linux发行版上运行。在OS X上,我必须使用ls -i file | cut -d ' ' -f 1
。
是否有某种方法可以在可跨* nix平台移植且不依赖于反复无常的shell脚本中查找文件的inode编号ls
?
Answers:
可能的解决方案:指定的POSIX规范ls
-i
,因此可能是可移植的。难道一个流行的实现的任何人都知道ls
这不不支持这一点,或把它打印从下面的例子中以不同的方式:
$ ls -di /
2 /
stat
命令在OS X ls -di
上不起作用,在这两者上都起作用。
ls
也具有-d
和-i
作为必选功能(尽管ls
它本身是可选的,与其他所有功能一样)。
ls
与-i
上至少的Solaris 10(可能的Solaris 11,我没有检查)前垫用空格。看起来这是回溯到Unix 7的传统行为,因此我怀疑很多公司的* nix风格都保持了这种行为(不过我手上只有Solaris 10)。据我所知,如果您使用正确地描绘了任意空格中的字段的东西(cut
例如,不是,而是awk
仅是shell自己的字段拆分),则可以很方便地将第一个非空白字符串作为索引节点数。
为了提高可移植性,您还可以statinode()
在stat
命令的基础上实现特定于平台的包装器功能(此处称为),该功能可以基于的输出uname -s
(请参阅uname)。
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
)
stat
是GNU Coreutils软件包的一部分。OSX使用不同的stat
实现(可能是基于BSD的实现),该实现不需要相同的命令行参数。
您总是可以在OSX上安装GNU Coreutils。当然,如果您需要一种适用于没有GNU Coreutils的OSX系统的解决方案,那将无济于事。
或者,如果我正确阅读了OSX stat(1)手册页,stat -f %i file
则OSX上的行为类似于stat -c %i file
使用Coreutils版本。(确定stat
您的版本是另一回事;您可以尝试stat --version >/dev/null
;如果成功,则说明您拥有GNU Coreutils版本。)
该ls -di
解决方案具有更高的可移植性和更少的麻烦,但这是另一种选择。
与jeff的方法类似,stat
也可以直接进行测试。
(
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
)