İnode numarasını bulmanın taşınabilir yolu


10

Kullanılan ilk yemek I stat -c %i file(yardım için hapis varlığını tespit güneş altında tüm Linux dağıtımları üzerinde çalışmaya görünüyordu). OS X'te kullanmak zorunda kaldım ls -i file | cut -d ' ' -f 1.

Kabuk betiğinde * nix platformları arasında taşınabilir olan ve herkesin bildiği gibi kaprisli olmayan bir dosyanın inode numarasını bulmanın bir yolu var mı ls?


1
Sen ilgilenen ya, daha iyi cevaplara sahip olabilir nasıl chroot içinde koşuyorum anlatır? .
Gilles 'SO- kötü olmayı bırak'

"Ünlü kaprisli ls" hakkında ayrıntılı bilgi verebilir misiniz?
jlliagre

@jlliagre: Diğerleri gelmiş yapmış zaten iyi.
l0b0

Tamam, bu tür dosyalar için cevabıma bakın.
jlliagre

Yanıtlar:


11

Olası çözüm: POSIX teknik özelliklerils belirtilmiştir -i, bu nedenle taşınabilirdir. Popüler bir uygulama bilen var mı lsyok ki değil aşağıdaki örnekten farklı bir şekilde bunu desteklemek ya onu yazdırır:

$ ls -di /
2 /

3
@jlliagre: Lütfen göndermeden önce okuyun. statKomut, OS X'te işe yaramadı ls -dihem çalıştı.
l0b0

1
Hatta Busybox lsvardır -dve -izorunlu özellikler olarak (gerçi lskendisi her şey gibi, isteğe bağlıdır).
Gilles 'SO- kötü olmayı bırak

1
Michael yanlış anlama tam olarak ne yorum vardı. Oldukça kaba ve hak edilmemiş "göndermeden önce okuyun" yorum değmez.
jlliagre

2
Orada şunlardır : bunun istisnaları lsile -i(muhtemelen Solaris 11, Kontrol etmedim) en az Solaris 10 üzerinde boşluklu ön pedleri. Görünüşe göre bu, Unix sürüm 7'ye geri dönen geleneksel davranıştı, bu yüzden kurumsal * nix lezzetlerinin birçoğunun bu davranışı sürdürdüğünden şüpheleniyorum (Sadece Solaris 10 var). Anlayabildiğim kadarıyla, gelişigüzel boşlukta alanları doğru bir şekilde tasvir eden bir şey kullanırsanız (yani, cutörneğin, awkveya sadece kabuğun kendi alan ayırması), ilk boşluk olmayan dizenin inode olmasını beklemek taşınabilir. numara.
mtraceur

1
@ l0b0 Evet. Mazoşist özveri gerektirir: sürekli azalan getiriler için bir grup çalışma / test ve ezber. En azından "taşınabilir" in bazı tanımları için mümkündür, ancak bu hoş bir deneyim değildir.
mtraceur

2

Bu taşınabilir olmalı ve ünlü kaprisli ls davranışına yol açan boşluklar, yeni satırlar veya diğer garip karakterler içeren dosya adları ile çalışmalıdır .

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

1

Taşınabilirliği artırmak için statinode(), statkomutun çıktısına dayalı olabilecek bir platforma özgü sarma işlevi de (burada çağrılır ) uygulayabilirsiniz uname -s(bkz. Uname ).

ls yalnızca yedek seçenek olarak gereklidir.

(
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 paketinin bir parçasıdır . OSX stat, aynı komut satırı bağımsız değişkenlerini almayan farklı bir uygulama (muhtemelen BSD tabanlı bir uygulama) kullanır .

GNU Coreutils'i OSX'e her zaman yükleyebilirsiniz. Tabii ki GNU Coreutils'e sahip olmayan OSX sistemlerinde çalışan bir çözüme ihtiyacınız varsa bu yardımcı olmaz.

Veya, OSX stat (1) kılavuz sayfasını doğru okuyorsam, OSX'te Coreutils sürümünü kullanmak stat -f %i filegibi davranır stat -c %i file. (Hangi sürümünüzün bulunduğunu belirlemek statbaşka bir konudur; deneyebilirsiniz stat --version >/dev/null; başarılı olursa, GNU Coreutils sürümüne sahipsiniz.)

ls -diSolüsyon daha taşınabilir ve daha az sorun olduğunu, ancak bu bir alternatiftir.


0

Başka bir çözüm:

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

Muhtemelen Perl'in kurulu olduğunu varsayabilirsiniz.


0

Jeff'in yaklaşımına benzer şekilde statdoğrudan da test edilebilir.

(
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
)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.