iノード番号を見つけるポータブルな方法


10

最初は私はstat -c %i file刑務所の存在検出するのを助けるために)使用しましたが、これは太陽の下でどのLinuxディストリビューションでも機能するように見えました。OS Xではを使用する必要がありましたls -i file | cut -d ' ' -f 1

* nixプラットフォーム間で移植可能で悪名高い気まぐれに依存しないシェルスクリプトでファイルのiノード番号を見つける方法はありますlsか?


1
、あなたに興味のある、またはのためのより良い答えを持ってすることができる私はchroot環境で実行している伝えるにはどうすればよいですか?
Gilles「SO-悪をやめる」

「悪名高い気まぐれなls」について詳しく教えてもらえますか?
jlliagre

@jlliagre:他の人はすでにそれをうまくやっていました。
l0b0

さて、そのようなファイルについては、私の返信を参照してください。
jlliagre

回答:


11

解決策:のためのPOSIX仕様ls指定は-i、ので、多分それは、ポータブルです。これをサポートしlsていない一般的な実装を知っている人や、次の例とは異なる方法で印刷する人はいますか?

$ ls -di /
2 /

3
@jlliagre:投稿する前に読んでください。statこのコマンドは、OS X上で動作しませんでしたls -diの両方で働いていました。
l0b0

1
Busyboxにも必須機能ls-dあり-iます(ls他のすべてと同様に、それ自体はオプションです)。
Gilles 'SO-悪をやめる'

1
マイケルの誤解はまさに私がコメントしていたことでした。それは、かなり失礼で不当な「投稿前に読む」コメントの価値はありません。
jlliagre

2
ありますこれに対する例外は:ls-i、少なくともSolaris 10でスペースをフロントパッド(おそらくSolarisの11は、私がチェックしていません)。これはUnixバージョン7にさかのぼる従来の動作のようです。そのため、多くの企業* nixフレーバーがこの動作を維持していると思います(ただし、手元にあるのはSolaris 10のみです)。私が知ることができるように、任意の空白でフィールドを適切に区切る何かを使用する場合(そうではなくcut、たとえば、awkまたはシェル自身のフィールド分割のみ)、最初の非空白文字列がiノードであると期待することは移植可能です数。
mtraceur 2016年

1
@ l0b0うん。それは自発的な献身を必要とします:リターンを絶えず減少させるためのたくさんの研究/テストと暗記。少なくとも「ポータブル」の定義によっては可能ですが、快適な体験ではありません。
mtraceur

2

これは移植性があり、スペース、改行、または悪名高い気まぐれな ls動作につながる他の奇妙な文字を含むファイル名で機能する必要があります。

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

1

移植性を高めるために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
)

0

statGNU Coreutilsパッケージの一部です。OSXはstat、同じコマンドライン引数をとらない別の実装(おそらくBSDベースの実装)を使用します。

OSXにはいつでもGNU Coreutilsをインストールできます。もちろん、GNU Coreutilsを持たないOSXシステムで動作するソリューションが必要な場合は、これは役に立ちません。

または、OSX stat(1)のマニュアルページを正しく読んでいる場合、OSXではCoreutilsバージョンを使用stat -f %i fileするように動作しstat -c %i fileます。(使用しているバージョンを判別statすることは別の問題です。試すこともできstat --version >/dev/nullます。成功した場合は、GNU Coreutilsバージョンを使用しています。)

ls -diソリューションは、よりポータブルかつ少ない手間であるが、これは代替手段です。


0

別の解決策:

#!/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がインストールされていると想定しても問題ありません。


0

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
)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.