[unix] 아이 노드 번호를 찾는 휴대용 방법

처음에는 stat -c %i file( 감옥의 존재를 감지하는 데 도움이 됨) 사용 했는데, 이는 태양 아래 어떤 Linux 배포에서도 작동하는 것 같습니다. OS X ‘에서는을 사용해야했습니다 ls -i file | cut -d ' ' -f 1.

쉘 스크립트에서 파일의 inode 번호를 찾는 방법이 있습니까? * nix 플랫폼에서 이식 가능하며 악명 높은 변덕에 의존하지 ls않습니까?



답변

가능한 해결책 :의 POSIX 사양은ls 지정 -i하므로 이식성이 있습니다. 누구든지 ls이것을 구현 하지 않는 인기있는 구현을 알고 있거나 다음 예제와 다른 방식으로 인쇄합니다.

$ ls -di /
2 /


답변

이것은 이식 가능해야하며 공백, 줄 바꿈 또는 기타 이상한 문자가 포함 된 파일 이름으로 작동하여 악명 높은 변덕스러운 ls 동작을 유발합니다 .

filename="whatever file name"
find . -name "$filename" -exec sh -c 'ls -di "$0" | head -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
)


답변

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솔루션은 이식성이 높고 문제가 적지 만 대안입니다.


답변

다른 해결책 :

#!/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이 설치되었다고 가정해도됩니다.


답변

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
)


답변