मै भागा
ln /a/A /b/B
मैं उस फ़ोल्डर को देखना चाहूँगा a
जहाँ फ़ाइल A को इंगित करता है ls
।
मै भागा
ln /a/A /b/B
मैं उस फ़ोल्डर को देखना चाहूँगा a
जहाँ फ़ाइल A को इंगित करता है ls
।
जवाबों:
आप अपनी फ़ाइल के लिए इनकोड नंबर पा सकते हैं
ls -i
तथा
ls -l
संदर्भ संख्या दिखाता है (किसी विशेष इनोड में हार्डलिंक की संख्या)
आपके द्वारा इनोड नंबर पाए जाने के बाद, आप एक ही इनोड के साथ सभी फाइलों को खोज सकते हैं:
find . -inum NUM
वर्तमान dir (।) में इनोड NUM के लिए फ़ाइल नाम दिखाएंगे।
आपके प्रश्न का वास्तव में एक अच्छी तरह से परिभाषित उत्तर नहीं है। सिमिलिंक के विपरीत, हार्डलिंक "मूल फ़ाइल" से अप्रभेद्य हैं।
निर्देशिका प्रविष्टियों में एक फ़ाइल नाम और एक सूचक इनोड होता है। बदले में इनकोड में फ़ाइल मेटाडेटा और (वास्तविक फ़ाइल सामग्री के लिए संकेत) समाहित है। एक हार्ड लिंक बनाने से एक ही फ़ाइल नाम + एक ही इनोड का संदर्भ बनता है। ये संदर्भ यूनिडायरेक्शनल हैं (विशिष्ट फाइल सिस्टम में, कम से कम) - इनोड केवल संदर्भ संख्या रखता है। यह पता लगाने का कोई आंतरिक तरीका नहीं है कि "मूल" फ़ाइल नाम क्या है।
वैसे, यही कारण है कि सिस्टम एक फ़ाइल को "हटाने" के लिए कहता है unlink
। यह सिर्फ एक हार्डलिंक को हटाता है। इनकोड संलग्न डेटा को केवल तभी हटा दिया जाता है जब इनोड का संदर्भ गणना 0 पर गिरती है।
किसी दिए गए इनोड के अन्य संदर्भों को खोजने का एकमात्र तरीका यह है कि फाइल सिस्टम चेकिंग पर पूरी तरह से खोज की जाए कि कौन सी फाइल इनोड को प्रश्न में संदर्भित करती है। आप इस जाँच को करने के लिए शेल से 'ए-एफ़ बी' का उपयोग कर सकते हैं।
UNIX में हार्ड लिंक और प्रतीकात्मक लिंक हैं ( क्रमशः "ln"
और "ln -s"
क्रमशः)। प्रतीकात्मक लिंक बस एक फ़ाइल है जिसमें किसी अन्य फ़ाइल का वास्तविक पथ है और फ़ाइल सिस्टम को पार कर सकता है।
हार्ड लिंक UNIX के शुरुआती दिनों से ही आस-पास रहे हैं (कि मैं वैसे भी याद कर सकता हूं, और यह काफी समय बाद वापस आ रहा है)। वे दो निर्देशिका प्रविष्टियाँ हैं जो सटीक अंतर्निहित डेटा का संदर्भ देती हैं । किसी फ़ाइल में डेटा इसके द्वारा निर्दिष्ट किया जाता है inode
। एक फ़ाइल सिस्टम पर प्रत्येक फ़ाइल एक इनोड की ओर इशारा करती है, लेकिन इसमें कोई आवश्यकता नहीं है कि प्रत्येक फ़ाइल एक अनूठे इनोड की ओर इंगित करती है - यहीं से हार्ड लिंक आते हैं।
चूंकि इनोड केवल किसी दिए गए फाइल सिस्टम के लिए अद्वितीय हैं, इसलिए एक सीमा है कि हार्ड लिंक एक ही फाइल सिस्टम (प्रतीकात्मक लिंक के विपरीत) पर होना चाहिए। ध्यान दें कि, प्रतीकात्मक लिंक के विपरीत, कोई विशेषाधिकार प्राप्त फ़ाइल नहीं है - वे सभी समान हैं। डेटा क्षेत्र केवल तब जारी किया जाएगा जब उस इनोड का उपयोग करने वाली सभी फाइलें हटा दी जाती हैं (और सभी प्रक्रियाएं इसे बंद भी करती हैं, लेकिन यह एक अलग मुद्दा है)।
आप "ls -i"
किसी विशेष फ़ाइल का इनकोड प्राप्त करने के लिए कमांड का उपयोग कर सकते हैं । आप तब "find <filesystemroot> -inum <inode>"
दिए गए इनोड के साथ फाइलसिस्टम पर सभी फाइलों को खोजने के लिए कमांड का उपयोग कर सकते हैं ।
यहाँ एक स्क्रिप्ट है जो वास्तव में ऐसा करती है। आप इसके साथ आह्वान करते हैं:
findhardlinks ~/jquery.js
और यह उस फाइल सिस्टम पर सभी फाइलों को खोजेगा जो उस फाइल के लिए हार्ड लिंक हैं:
pax@daemonspawn:~# ./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
. ./findhardlinks.bash
OS X के Zsh में रहते हुए शुरू करता हूं। स्क्रीन में मेरी वर्तमान विंडो बंद हो जाती है।
INUM=$(stat -c %i $1)
। इसके अलावा NUM_LINKS=$(stat -c %h $1)
। man stat
अधिक वैरिएबल वैरिएबल के लिए देखें जिनका आप उपयोग कर सकते हैं।
ls -l
पहला कॉलम अनुमतियों का प्रतिनिधित्व करेगा। दूसरा कॉलम फाइल के लिए उप-आइटम (निर्देशिकाओं के लिए) या एक ही डेटा (हार्ड लिंक, मूल फ़ाइल सहित) के पथों की संख्या होगी। उदाहरण के लिए:
-rw-r--r--@ 2 [username] [group] [timestamp] HardLink
-rw-r--r--@ 2 [username] [group] [timestamp] Original
^ Number of hard links to the data
inode
बारी-बारी से डिस्क सामग्री की ओर इशारा करते हैं।
निम्नलिखित में से एक सरल कैसे है? (लैटर ऊपर की लंबी लिपियों की जगह ले सकता है!)
यदि आपके पास कोई विशिष्ट फ़ाइल है <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 {} \;
-type f
क्योंकि फ़ाइल एक निर्देशिका भी हो सकती है।
.
और ..
निर्देशिका में प्रविष्टियों hardlinks हैं। आप बता सकते हैं कि लिंक की गिनती से एक निर्देशिका में कितने उपखंड हैं .
। यह वैसे भी मूट है, क्योंकि find -samefile .
अभी भी कोई subdir/..
आउटपुट नहीं आएगा । find
(कम से कम GNU संस्करण) को अनदेखा करने के लिए हार्डकोड किया गया लगता है ..
, यहां तक कि साथ भी -noleaf
।
O(n^2)
, और find
हार्डलिंक फ़ाइलों के सेट के प्रत्येक सदस्य के लिए एक बार चलता है । find ... -printf '%16i %p\n' | sort -n | uniq -w 16 --all-repeated=separate
काम करेंगे, (16 2 ^ 63-1 के एक दशमलव प्रतिनिधित्व के लिए पर्याप्त चौड़ा नहीं है, इसलिए जब आपका XFS फाइलसिस्टम इनोड संख्याओं को उच्च करने के लिए काफी बड़ा है, तो बाहर देखें)
एक फाइल सिस्टम में सभी हार्डलिंक को खोजने के लिए स्क्रिप्ट के साथ बहुत सारे उत्तर हैं। उनमें से ज्यादातर मूर्खतापूर्ण चीजों -samefile
से जुड़ी हैं जैसे कि EACH मल्टीप्ल लिंक्ड फ़ाइल के लिए संपूर्ण फाइल सिस्टम को स्कैन करने के लिए रनिंग फाइंड। यह पागलपन है; आपको केवल इनकोड संख्या और प्रिंट डुप्लिकेट पर सॉर्ट करना है।
हार्डलिंक की गई फ़ाइलों के सभी सेटों को खोजने और उन्हें समूहीकृत करने के लिए फाइल सिस्टम पर केवल एक पास के साथ
find dirs -xdev \! -type d -links +1 -printf '%20D %20i %p\n' |
sort -n | uniq -w 42 --all-repeated=separate
यह हार्डलिंक की गई फ़ाइलों के कई सेट खोजने के लिए अन्य उत्तरों की तुलना में बहुत तेज है ।
find /foo -samefile /bar
सिर्फ एक फ़ाइल के लिए उत्कृष्ट है।
-xdev
: एक फाइलसिस्टम की सीमा। कड़ाई की जरूरत नहीं है क्योंकि हम एफएस-आईडी को यूनीक पर भी प्रिंट करते हैं! -type d
निर्देशिकाओं को अस्वीकार करें: .
और ..
प्रविष्टियों का मतलब है कि वे हमेशा जुड़े हुए हैं।-links +1
: लिंक गिनती सख्ती से करें > 1
-printf ...
एफएस-आईडी, इनकोड संख्या और पथ प्रिंट करें। (निश्चित कॉलम चौड़ाई के लिए पैडिंग के साथ जिसके uniq
बारे में हम बता सकते हैं ।)sort -n | uniq ...
संख्यात्मक 42 प्रकार और पहले 42 कॉलम पर एक अलग लाइन के साथ समूहों को अलग करनाउपयोग करने का ! -type d -links +1
मतलब है कि सॉर्ट का इनपुट यूनीक के अंतिम आउटपुट जितना बड़ा है, इसलिए हम बड़ी मात्रा में स्ट्रिंग छँटाई नहीं कर रहे हैं। जब तक आप इसे एक उपनिर्देशिका पर नहीं चलाते हैं जिसमें केवल हार्डलिंक का एक सेट होता है। वैसे भी, यह किसी भी अन्य पोस्ट किए गए समाधान की तुलना में फाइल सिस्टम को फिर से ट्रैवर्सिंग में बहुत कम सीपीयू समय का उपयोग करेगा।
नमूना उत्पादन:
...
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 ?: संयुक्त राष्ट्र पैड के साथ awk
या उत्पादन cut
। uniq
बहुत सीमित क्षेत्र-चयन का समर्थन है, इसलिए मैं आउटपुट खोजता हूं और निश्चित-चौड़ाई का उपयोग करता हूं। अधिकतम संभव इनोड या डिवाइस नंबर (2 ^ 64-1 = 18446744073709551616) के लिए 20chars पर्याप्त चौड़ा है। XFS उन डिस्क के आधार पर इनकोड संख्या चुनता है, जहां वे डिस्क पर आबंटित हैं, 0 से सन्निहित नहीं हैं, इसलिए बड़े XFS फाइलसिस्टम में> 32 बिट इनकोड संख्याएँ हो सकती हैं, भले ही उनके पास अरबों फाइलें न हों। अन्य फ़ाइल सिस्टम में 20-अंकीय संख्या हो सकती है, भले ही वे विशाल न हों।
TODO: मार्ग से डुप्लिकेट के समूह। उन्हें माउंट पॉइंट के द्वारा क्रमबद्ध करने के बाद, इनोड नंबर चीजों को एक साथ मिलाता है, अगर आपके पास कुछ अलग-अलग उपखंड हैं जिनमें बहुत सारे हार्डलिंक हैं। (अर्थात डुप-समूह के समूह एक साथ चलते हैं, लेकिन आउटपुट उन्हें मिलाता है)।
एक अंतिम sort -k 3
लाइनों को अलग-अलग क्रमबद्ध करेगा, न कि एकल रिकॉर्ड के रूप में लाइनों के समूह। NUL बाइट में न्यूलाइन्स की एक जोड़ी को बदलने के लिए कुछ के साथ प्रीप्रोसेसिंग करना, और GNU का उपयोग sort --zero-terminated -k 3
करना हो सकता है। tr
केवल एकल वर्णों पर संचालित होता है, न कि 2-> 1 या 1-> 2 पैटर्न, हालांकि। perl
यह करना होगा (या बस पार्सल और perl या awk के भीतर सॉर्ट)। sed
काम भी हो सकता है।
%D
फाइल सिस्टम पहचानकर्ता (यह वर्तमान बूट के लिए अद्वितीय है, जबकि कोई फ़ाइल सिस्टम रहे हैं umount
एड), तो निम्न और भी अधिक सामान्य है: find directories.. -xdev ! -type d -links +1 -printf '%20i %20D %p\n' | sort -n | uniq -w 42 --all-repeated=separate
। यह तब तक काम करता है जब तक कि किसी दिए गए निर्देशिका में फाइलसिस्टम स्तर पर कोई अन्य निर्देशिका न हो, यह भी सब कुछ देखता है जिसे हार्डलिंक किया जा सकता है (जैसे डिवाइस या सॉफ्टलिंक - हां, सॉफ्टलिंक की लिंक 1 से अधिक हो सकती है)। ध्यान दें कि dev_t
और ino_t
आज 64 बिट लंबा है। यह संभावना तब तक रहेगी जब तक हमारे पास 64 बिट सिस्टम होंगे।
! -type d
इसके बजाय का उपयोग करने के बारे में महान बिंदु -type f
। मैं भी अपने filesystem पर कुछ संग्रह फ़ाइलों के आयोजन से कुछ हार्डलिंक सहानुभूति है। आपके बेहतर संस्करण के साथ मेरे उत्तर को अपडेट करें (लेकिन मैंने पहले fs-id डाल दिया, इसलिए फाइलसिस्टम द्वारा कम से कम समूहों को क्रमबद्ध करें।)
यह कुछ हद तक 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
वैरिएबल पर चयन करना । यह प्रोसेस इनवोकेशन को बचाएगा, जो हार्ड वर्किंग स्क्रिप्ट में लगभग हमेशा बेटर्स के प्रदर्शन को गंभीर रूप से प्रभावित करता है।
आपका egrep
s सिर्फ और सिर्फ हो सकता है grep
।
find ... -xdev -type f -links +1 -printf '%16i %p\n' | sort -n | uniq -w 16 --all-repeated=separate
। यह MUCH अधिक तेज़ है, क्योंकि यह केवल एक बार fs का पता लगाता है। एक साथ कई एफएस के लिए, आपको एफएस आईडी के साथ इनकोड संख्याओं को उपसर्ग करना होगा। हो सकता हैfind -exec stat... -printf ...
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 "";
एक GUI समाधान वास्तव में आपके प्रश्न के करीब हो जाता है:
आप वास्तविक हार्डलिंक फ़ाइलों को "ls" से सूचीबद्ध नहीं कर सकते क्योंकि, जैसा कि पिछले टिप्पणीकारों ने बताया है, फ़ाइल "नाम" समान डेटा के लिए केवल उपनाम हैं। हालांकि, वास्तव में एक जीयूआई उपकरण है जो वास्तव में आप जो चाहते हैं उसके करीब हो जाता है जो कि फाइल नामों की एक पथ लिस्टिंग प्रदर्शित करना है जो लिनक्स के तहत एक ही डेटा (हार्डलिंक के रूप में) को इंगित करता है, इसे एफएसएलआईएनटी कहा जाता है। आप जो विकल्प चाहते हैं, वह खोज (XX) में "नाम क्लैश" -> अचयनित "चेकबॉक्स $ PATH" के तहत है -> और शीर्ष-मध्य की ओर "के लिए ... के बाद ड्रॉप-डाउन बॉक्स से" उपनाम "चुनें।
FSLint को बहुत खराब तरीके से प्रलेखित किया गया है, लेकिन मैंने पाया कि "रिकार्से?" के लिए चयनित चेकबॉक्स के साथ "सर्च पाथ" के तहत सीमित डायरेक्टरी ट्री सुनिश्चित करते हैं? और उपर्युक्त विकल्प, पथ और नामों के साथ हार्डलिंक डेटा की एक सूची जो प्रोग्राम खोज के बाद उसी डेटा में "बिंदु" उत्पन्न होते हैं।
आप ls
'उपनाम' का उपयोग करके हार्डलिंक को हाइलाइट करने के लिए कॉन्फ़िगर कर सकते हैं , लेकिन जैसा कि पहले कहा गया था कि हार्डलिंक के 'स्रोत' को दिखाने का कोई तरीका नहीं है, यही कारण है कि मैं इसके .hardlink
साथ मदद करने के लिए अपील करता हूं ।
अपने में कहीं निम्नलिखित जोड़ें .bashrc
alias ll='LC_COLLATE=C LS_COLORS="$LS_COLORS:mh=1;37" ls -lA --si --group-directories-first'
link(2)
सिस्टम कॉल के बाद , इसका कोई अर्थ नहीं है जिसमें एक मूल है और एक लिंक है। यही कारण है कि, जैसा कि उत्तर बताते हैं, सभी लिंक खोजने का एकमात्र तरीका हैfind / -samefile /a/A
। क्योंकि एक इनोड के लिए एक निर्देशिका प्रविष्टि एक ही इनोड के लिए अन्य निर्देशिका प्रविष्टियों के बारे में "नहीं जानती"। वे सभी करते हैं कि इनकोड को रिफंड किया जाता है ताकि इसे हटा दिया जा सके जब इसके लिए अंतिम नाम होunlink(2)ed
। (यहls
आउटपुट में "लिंक काउंट" है )।