Maneira portátil de encontrar o número do inode

10

Primeiro, usei stat -c %i file (para ajudar a detectar a presença de uma cadeia ), que parecia funcionar em qualquer distribuição Linux sob o sol. No OS X 'eu tive que usar ls -i file | cut -d ' ' -f 1 .

Existe alguma maneira de encontrar o número de inode de um arquivo em um script de shell que seja portátil em plataformas * nix e não dependa do notoriamente caprichoso ls ?

    
por l0b0 08.11.2011 / 13:46

6 respostas

11

Solução possível: A especificação POSIX para ls especifica -i , então talvez é portável. Alguém sabe de uma implementação popular de ls que não suporta isso, ou imprime de forma diferente do seguinte exemplo:

$ ls -di /
2 /
    
por 08.11.2011 / 13:50
2

Isso deve ser portável e funcionar com nomes de arquivos que contenham espaços, novas linhas ou outros caracteres estranhos, levando ao comportamento notoriamente caprichoso de ls.

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

Para aumentar a portabilidade, você também pode implementar uma função de wrapper específica da plataforma (aqui chamada statinode() ) em torno do comando stat que pode ser baseado na saída de uname -s (consulte uname ).

ls seria necessário apenas como opção de fallback.

(
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
)
    
por 10.11.2011 / 13:55
0

stat faz parte do pacote GNU Coreutils . O OSX usa uma implementação diferente de stat (presumivelmente baseada em BSD) que não aceita os mesmos argumentos de linha de comando.

Você sempre pode instalar o GNU Coreutils no OSX. Claro que isso não ajuda se você precisar de uma solução que funcione em sistemas OSX que não possuam o GNU Coreutils.

Ou, se eu estiver lendo o stat do OSX (1) man page corretamente, stat -f %i file no OSX se comporta como stat -c %i file usando a versão Coreutils. (Determinar qual versão de stat você tem é outra questão; você pode tentar stat --version >/dev/null ; se tiver sucesso, você terá a versão GNU Coreutils.)

A solução ls -di é mais portável e menos problemática, mas isso é uma alternativa.

    
por 09.11.2011 / 21:59
0

Outra solução:

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

Você provavelmente pode presumir com segurança que o Perl está instalado.

    
por 09.11.2011 / 22:00
0

Similar à abordagem de jeff, stat poderia ser testado diretamente também.

(
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
)
    
por 13.11.2011 / 10:46

Tags