it-swarm.asia

كيف يمكنك رؤية الرابط الثابت الفعلي بواسطة ls؟

انا اجري

ln /a/A /b/B

أود أن أرى في المجلد a حيث يشير الملف A إلى ls.

91
Léo Léopold Hertz 준영

يمكنك العثور على رقم inode لملفك مع

ls -i

و

ls -l

يُظهر عدد المراجع (عدد الارتباطات الثابتة إلى inode معين)

بعد العثور على رقم inode ، يمكنك البحث عن جميع الملفات التي لها نفس inode:

find . -inum NUM

سيعرض أسماء ملفات inode NUM بالقيمة الحالية (.)

163
zzr

لا يوجد حقا إجابة محددة لسؤالك. على عكس الارتباطات ، لا يمكن تمييز الروابط الصلبة عن "الملف الأصلي".

تتكون إدخالات الدليل من اسم ملف ومؤشر إلى inode. يحتوي inode بدوره على البيانات الأولية للملف و (يشير إلى) محتويات الملف الفعلية). يؤدي إنشاء ارتباط ثابت إلى إنشاء اسم ملف آخر + مرجع إلى نفس inode. هذه المراجع أحادية الاتجاه (في أنظمة الملفات النموذجية ، على الأقل) - يحتفظ inode فقط بعدد مرجعي. لا توجد طريقة جوهرية لمعرفة اسم الملف "الأصلي".

بالمناسبة ، هذا هو سبب استدعاء النظام "لحذف" ملف unlink. إنه فقط يزيل الارتباط الصلب. يتم حذف inode البيانات المرفقة فقط إذا انخفض عدد مرجع inode إلى 0.

الطريقة الوحيدة للعثور على المراجع الأخرى إلى inode المعطى هي البحث بشكل شامل عبر نظام الملفات للتحقق من الملفات التي تشير إلى inode في السؤال. يمكنك استخدام "اختبار A -ef B" من Shell لإجراء هذا الاختيار.

60
Laurence Gonsalves

لدى UNIX ارتباطات ثابتة وروابط رمزية (تم إنشاؤها باستخدام "ln" و "ln -s" على التوالي). الروابط الرمزية هي ببساطة ملف يحتوي على المسار الحقيقي لملف آخر ويمكنه عبور أنظمة الملفات.

كانت الروابط الثابتة موجودة منذ الأيام الأولى لـ UNIX (التي يمكنني أن أتذكرها على أي حال ، وهذا يعود لفترة طويلة). وهما إدخالات دليل تشير إلى بالضبط نفس البيانات الأساسية. يتم تحديد البيانات في ملف بواسطة inode. يشير كل ملف على نظام ملفات إلى inode لكن لا يوجد أي شرط بأن يشير كل ملف إلى inode فريد - حيث تأتي الروابط الثابتة.

نظرًا لأن inodes فريدة من نوعها لنظام ملفات معين فقط ، فهناك قيود على أن الروابط الثابتة يجب أن تكون على نظام الملفات نفسه (على عكس الروابط الرمزية). لاحظ أنه ، على عكس الروابط الرمزية ، لا يوجد ملف متميز - كلهم ​​متساوون. لن يتم إصدار منطقة البيانات إلا عند حذف جميع الملفات التي تستخدم هذا inode (وإغلاق جميع العمليات أيضًا ، ولكن هذه مشكلة مختلفة).

يمكنك استخدام الأمر "ls -i" للحصول على inode لملف معين. يمكنك حينئذٍ استخدام الأمر "find <filesystemroot> -inum <inode>" للعثور على جميع الملفات على نظام الملفات مع ذلك inode المعطى.

إليك النص الذي يفعل ذلك بالضبط. يمكنك استدعاء ذلك بـ:

findhardlinks ~/jquery.js

وسيجد كل الملفات الموجودة على نظام الملفات تلك روابط صلبة لهذا الملف:

[email protected]:~# ./findhardlinks /home/pax/jquery.js
Processing '/home/pax/jquery.js'
   '/home/pax/jquery.js' has inode 5211995 on mount point '/'
       /home/common/jquery-1.2.6.min.js
       /home/pax/jquery.js

هنا النص.

#!/bin/bash
if [[ $# -lt 1 ]] ; then
    echo "Usage: findhardlinks <fileOrDirToFindFor> ..."
    exit 1
fi

while [[ $# -ge 1 ]] ; do
    echo "Processing '$1'"
    if [[ ! -r "$1" ]] ; then
        echo "   '$1' is not accessible"
    else
        numlinks=$(ls -ld "$1" | awk '{print $2}')
        inode=$(ls -id "$1" | awk '{print $1}' | head -1l)
        device=$(df "$1" | tail -1l | awk '{print $6}')
        echo "   '$1' has inode ${inode} on mount point '${device}'"
        find ${device} -inum ${inode} 2>/dev/null | sed 's/^/        /'
    fi
    shift
done
33
user53528
ls -l

سيمثل العمود الأول الأذونات. سيكون العمود الثاني هو عدد العناصر الفرعية (للأدلة) أو عدد المسارات إلى نفس البيانات (الارتباطات الثابتة ، بما في ذلك الملف الأصلي) إلى الملف. على سبيل المثال:

[email protected]    2    [username]    [group]    [timestamp]     HardLink
[email protected]    2    [username]    [group]    [timestamp]     Original
               ^ Number of hard links to the data
24
eyelidlessness

ماذا عن أبسط التالي واحد؟ (قد يحل محل النصوص النصية الطويلة أعلاه!)

إذا كان لديك ملف معين <THEFILENAME> وترغب في معرفة كافة الارتباطات الثابتة الخاصة به موزعة على الدليل <TARGETDIR> ، (والتي يمكن أن تكون حتى نظام الملفات بأكمله برمز /)

find <TARGETDIR> -type f -samefile  <THEFILENAME>

توسيع المنطق ، إذا كنت تريد معرفة جميع الملفات الموجودة في <SOURCEDIR> والتي تحتوي على روابط ثابتة متعددة موزعة على <TARGETDIR>:

find <SOURCEDIR> -type f -links +1   \
  -printf "\n\n %n HardLinks of file : %H/%f  \n"   \
  -exec find <TARGETDIR> -type f -samefile {} \; 
11
Loves Probability

هناك الكثير من الإجابات مع البرامج النصية للعثور على جميع الروابط الصلبة في نظام الملفات. يقوم معظمهم بأشياء سخيفة مثل الجري للعثور على نظام الملفات بالكامل لمسح -samefile لكل ملف مرتبط بتعدد. هذا جنون؛ كل ما تحتاجه هو فرز عدد inode وطباعة التكرارات.

find directories.. -xdev ! -type d -links +1 -printf '%20D %20i %p\n' | sort -n | uniq -w 42 --all-repeated=separate (شكرًا علىTino على التغيير في أمري الأصلي لدعم معرف FS (%D) ، وللتعامل مع جميع أنواع الملفات غير المرتبطة بالدليل ، وليس فقط الملفات العادية. سيؤدي ذلك إلى العثور على الارتباطات متعددة الارتباطات والأنابيب وما إلى ذلك)

استخدام ! -type d -links +1 يعني أن مدخلات الفرز أكبر من الناتج النهائي لـ uniq. إلا إذا قمت بتشغيله على دليل فرعي يحتوي فقط على مجموعة من الارتباطات الثابتة. على أي حال ، سوف يستخدم هذا وقتًا أقل بكثير لوحدة المعالجة المركزية لإعادة اجتياز نظام الملفات من أي حل آخر منشور.

إخراج العينة:

...
            2429             76732484 /home/peter/weird-filenames/test/.hiddendir/foo bar
            2429             76732484 /home/peter/weird-filenames/test.orig/.hiddendir/foo bar

            2430             17961006 /usr/bin/pkg-config.real
            2430             17961006 /usr/bin/x86_64-pc-linux-gnu-pkg-config

            2430             36646920 /usr/lib/i386-linux-gnu/dri/i915_dri.so
            2430             36646920 /usr/lib/i386-linux-gnu/dri/i965_dri.so
            2430             36646920 /usr/lib/i386-linux-gnu/dri/nouveau_vieux_dri.so
            2430             36646920 /usr/lib/i386-linux-gnu/dri/r200_dri.so
            2430             36646920 /usr/lib/i386-linux-gnu/dri/radeon_dri.so
...

TODO ؟: الامم المتحدة وسادة الإخراج. uniq لديه دعم محدود للغاية في مجال الاختيار ، لذلك أجد مخرجات البحث وأستخدم العرض الثابت. 20chars واسعة بما يكفي لأقصى حد ممكن inode أو رقم الجهاز (2 ^ 64-1 = 18446744073709551615). يختار XFS أرقام inode استنادًا إلى المكان الذي يتم تخصيصه فيه على القرص ، وليس بشكل متقطع من 0 ، لذلك يمكن أن تحتوي أنظمة ملفات XFS الكبيرة على>> أرقام 32bit inode حتى إذا لم يكن لديها مليارات الملفات. قد تحتوي أنظمة الملفات الأخرى على أرقام inode مكونة من 20 رقمًا حتى لو لم تكن هائلة.

TODO: فرز مجموعات من التكرارات حسب المسار. بعد فرزها حسب نقطة التحميل ، يقوم رقم inode بخلط الأشياء معًا ، إذا كان لديك زوجان فرعيان مختلفان يحتويان على الكثير من الارتباطات الثابتة. (بمعنى أن مجموعات المجموعات المزدوجة تتقارب معًا ، لكن الناتج يخلطها).

يقوم sort -k 3 النهائي بترتيب الأسطر بشكل منفصل ، وليس مجموعات الخطوط كسجل واحد. قد تؤدي المعالجة المسبقة بشيء ما لتحويل زوج من الأسطر الجديدة إلى بايت NUL ، واستخدام GNU sort --zero-terminated -k 3 للخدعة. tr يعمل فقط على أحرف مفردة ، وليس على أنماط 2 -> 1 أو 1-> 2. Perl سيفعل ذلك (أو مجرد تحليل وفرز داخل Perl أو awk). sed قد تعمل أيضًا.

4
Peter Cordes

هذا تعليق إلى حد ما على إجابة ونصوص Torocoro-Macho الخاصة ، لكن من الواضح أنه لن يصلح في مربع التعليقات.


أعد كتابة النص البرمجي الخاص بك بطرق أكثر وضوحًا للعثور على المعلومات ، وبالتالي تقليل عمليات الاستدعاء.

#!/bin/sh
xPATH=$(readlink -f -- "${1}")
for xFILE in "${xPATH}"/*; do
    [ -d "${xFILE}" ] && continue
    [ ! -r "${xFILE}" ] && printf '"%s" is not readable.\n' "${xFILE}" 1>&2 && continue
    nLINKS=$(stat -c%h "${xFILE}")
    if [ ${nLINKS} -gt 1 ]; then
        iNODE=$(stat -c%i "${xFILE}")
        xDEVICE=$(stat -c%m "${xFILE}")
        printf '\nItem: %s[%d] = %s\n' "${xDEVICE}" "${iNODE}" "${xFILE}";
        find "${xDEVICE}" -inum ${iNODE} -not -path "${xFILE}" -printf '     -> %p\n' 2>/dev/null
    fi
done

لقد حاولت أن أبقيه مشابهًا لك قدر الإمكان لمقارنته بسهولة.

تعليقات على هذا السيناريو ولك

  • يجب على المرء دائمًا تجنب السحر $IFS إذا كانت الكرة الأرضية كافية ، نظرًا لأنه ملفوف بشكل غير ضروري ، ويمكن أن تحتوي أسماء الملفات على سطور جديدة (ولكن في الممارسة العملية في المقام الأول السبب الأول).

  • يجب عليك تجنب التحليل اليدوي ls ومثل هذا الإخراج قدر الإمكان ، لأنه سوف يعضك عاجلاً أم آجلاً. على سبيل المثال: في أول سطر awk ، تفشل في جميع أسماء الملفات التي تحتوي على مسافات.

  • printf سيوفر في الغالب المتاعب في النهاية لأنه قوي للغاية مع بناء جملة %s. كما يمنحك التحكم الكامل في الإخراج ، وهو ثابت عبر جميع أنظمة ، على عكس echo.

  • stat يمكن أن يوفر لك الكثير من المنطق في هذه الحالة.

  • GNU find قوي.

  • دعواتك head و tail كان من الممكن التعامل معها مباشرة بـ awk باستخدام مثال الأمر exit و/أو التحديد في المتغير NR. هذا من شأنه أن ينقذ عمليات الاستدعاء العملية ، والتي تقريبًا تقسم الأداء بشدة في البرامج النصية الشاقة.

  • egreps الخاص بك يمكن أن يكون كذلك grep.

3
Daniel Andersson

استنادًا إلى البرنامج النصي findhardlinks (أعيد تسميته إلى hard-links) ، هذا ما قمت بإعادة تشكيله وجعله يعمل.

انتاج:

# ./hard-links /root

Item: /[10145] = /root/.profile
    -> /proc/907/sched
    -> /<some-where>/.profile

Item: /[10144] = /root/.tested
    -> /proc/907/limits
    -> /<some-where else>/.bashrc
    -> /root/.testlnk

Item: /[10144] = /root/.testlnk
    -> /proc/907/limits
    -> /<another-place else>/.bashrc
    -> /root/.tested

# cat ./hard-links
#!/bin/bash
oIFS="${IFS}"; IFS=$'\n';
xPATH="${1}";
xFILES="`ls -al ${xPATH}|egrep "^-"|awk '{print $9}'`";
for xFILE in ${xFILES[@]}; do
  xITEM="${xPATH}/${xFILE}";
  if [[ ! -r "${xITEM}" ]] ; then
    echo "Path: '${xITEM}' is not accessible! ";
  else
    nLINKS=$(ls -ld "${xITEM}" | awk '{print $2}')
    if [ ${nLINKS} -gt 1 ]; then
      iNODE=$(ls -id "${xITEM}" | awk '{print $1}' | head -1l)
      xDEVICE=$(df "${xITEM}" | tail -1l | awk '{print $6}')
      echo -e "\nItem: ${xDEVICE}[$iNODE] = ${xITEM}";
      find ${xDEVICE} -inum ${iNODE} 2>/dev/null|egrep -v "${xITEM}"|sed 's/^/   -> /';
    fi
  fi
done
IFS="${oIFS}"; echo "";
2
Torocoro-Macho

يقترب حل واجهة المستخدم الرسومية من سؤالك:

لا يمكنك سرد الملفات الفعلية ذات الارتباط الثابت من "ls" لأنه ، كما أشار المعلقون السابقون ، فإن "أسماء" الملفات ليست سوى أسماء مستعارة لنفس البيانات. ومع ذلك ، هناك بالفعل أداة واجهة المستخدم الرسومية التي تقترب بالفعل من ما تريده وهو عرض قائمة مسار أسماء الملفات التي تشير إلى نفس البيانات (مثل الروابط الصلبة) تحت لينكس ، ويسمى FSLint. الخيار الذي تريده موجود أسفل "clashes name" -> ألغ تحديد "check box $ PATH" في Search (XX) -> وحدد "Aliases" من المربع المنسدل بعد "for ..." نحو الأعلى - الأوسط.

تم توثيق FSLint بشكل سيئ للغاية لكنني وجدت أنه تأكد من وجود شجرة دليل محدودة ضمن "مسار البحث" مع تحديد خانة الاختيار "Recurse؟" يتم إنتاج الخيارات المذكورة أعلاه ، وقائمة من البيانات ذات الارتباط الثابت مع المسارات والأسماء التي "تشير" إلى نفس البيانات بعد البحث في البرنامج.

1
Charles

يمكنك تكوين ls لتمييز الارتباطات الثابتة باستخدام "اسم مستعار" ، ولكن كما هو مذكور سابقًا ، لا توجد طريقة لإظهار "مصدر" الرابط الثابت وهذا هو سبب إلحاقي .hardlink للمساعدة في ذلك.

highlight hardlinks

أضف ما يلي في مكان ما في .bashrc

alias ll='LC_COLLATE=C LS_COLORS="$LS_COLORS:mh=1;37" ls -lA --si --group-directories-first'
1
Daniel Sokolowski