मैं टूटी सहानुभूति कैसे पा सकता हूं


281

क्या सभी प्रतीकात्मक लिंक खोजने का एक तरीका है जो किसी भी बिंदु को इंगित नहीं करता है?

find ./ -type l

मुझे सभी प्रतीकात्मक लिंक देगा, लेकिन उन लिंक के बीच कोई अंतर नहीं करता है जो कहीं जाते हैं और लिंक जो नहीं करते हैं।

मैं वर्तमान में कर रहा हूँ:

find ./ -type l -exec file {} \; |grep broken

लेकिन मैं सोच रहा हूं कि क्या वैकल्पिक समाधान मौजूद हैं।

जवाबों:


351

मैं दृढ़ता से सुझाव देना चाहता हूं कि कार्य के लिए उपयोग करें find -L(स्पष्टीकरण के लिए नीचे देखें)। ऐसा करने के कुछ अन्य तरीके यहां दिए गए हैं:

  • यदि आप "शुद्ध find" विधि का उपयोग करना चाहते हैं , तो इसे इस तरह दिखना चाहिए:

    find . -xtype l
    

    ( xtypeएक परीक्षण किया गया लिंक पर प्रदर्शन किया जाता है) यह सभी संस्करणों में उपलब्ध नहीं हो सकता है find, हालाँकि। लेकिन अन्य विकल्प भी हैं:

  • आप कमांड के test -eभीतर से भी निष्पादित कर सकते हैं find:

    find . -type l ! -exec test -e {} \; -print
    
  • यहां तक ​​कि कुछ grepट्रिक (यानी, सुरक्षित ) की तुलना में बेहतर हो सकती हैं find -L, लेकिन बिल्कुल नहीं जैसे कि प्रश्न में प्रस्तुत किया गया है (जो पूरे आउटपुट लाइनों में शामिल है, जिसमें फ़ाइल नाम भी शामिल है):

     find . -type l -exec sh -c 'file -b "$1" | grep -q ^broken' sh {} \; -print
    

find -Lचाल उद्धृत एकल द्वारा से commandlinefu अच्छा और hacky लग रहा है, लेकिन यह एक बहुत है खतरनाक ख़तरा : सभी सिमलिंक पीछा कर रहे हैं। नीचे प्रस्तुत सामग्री के साथ निर्देशिका पर विचार करें:

$ ls -l
total 0
lrwxrwxrwx 1 michal users  6 May 15 08:12 link_1 -> nonexistent1
lrwxrwxrwx 1 michal users  6 May 15 08:13 link_2 -> nonexistent2
lrwxrwxrwx 1 michal users  6 May 15 08:13 link_3 -> nonexistent3
lrwxrwxrwx 1 michal users  6 May 15 08:13 link_4 -> nonexistent4
lrwxrwxrwx 1 michal users 11 May 15 08:20 link_out -> /usr/share/

यदि आप find -L . -type lउस निर्देशिका में चलते हैं , तो सभी /usr/share/को खोजा जाएगा (और यह वास्तव में लंबा समय ले सकता है) 1एक findकमांड के लिए जो "आउटगोइंग लिंक के लिए प्रतिरक्षा है", का उपयोग न करें-L


1 यह एक छोटी सी असुविधा की तरह लग सकता है (कमांड "बस" लंबे समय तक सभी को पार करने में लगेगा /usr/share) - लेकिन अधिक गंभीर परिणाम हो सकते हैं। उदाहरण के लिए, चेरोट वातावरण पर विचार करें: वे मुख्य फाइलसिस्टम के कुछ उपनिर्देशिका में मौजूद हो सकते हैं और पूर्ण स्थानों के लिए सीमलिंक शामिल कर सकते हैं। उन लिंक को "बाहर" सिस्टम के लिए तोड़ा जा सकता है, क्योंकि वे केवल एक बार उचित स्थानों की ओर इशारा करते हैं जब आप चुरोट में प्रवेश करते हैं। मुझे यह भी याद है कि कुछ बूटलोडर ने सिर्लिंक का इस्तेमाल किया था, /bootजो कि शुरुआती बूट फेज़ में ही समझ में आता था, जब बूट पार्टीशन को माउंट किया गया था /

इसलिए यदि आप find -Lखोजने के लिए एक कमांड का उपयोग करते हैं और फिर कुछ हानिरहित दिखने वाली निर्देशिका से टूटे हुए सीमलिंक को हटाते हैं, तो आप अपने सिस्टम को भी तोड़ सकते हैं ...


11
मुझे लगता -type lहै कि गैर-लिंक के -xtype lरूप में काम करेंगे के बाद से अनावश्यक है -type l। तो find -xtype lशायद आप सभी की जरूरत है। इस दृष्टिकोण के लिए धन्यवाद।
21

3
ज्ञात हो कि वे समाधान सभी फाइलसिस्टम प्रकारों के लिए काम नहीं करते हैं। उदाहरण के लिए यह जाँचने के लिए काम नहीं करेगा कि क्या /proc/XXX/exeलिंक टूटा हुआ है। इसके लिए, का उपयोग करें test -e "$(readlink /proc/XXX/exe)"
क्वाटर्जेगुई

2
@ फीलम का find . -xtype lअर्थ है "वे सभी सिम्बलिंक जिनके (अंतिम) टार्गेट फाइल्स सिमिलिंक हैं"। लेकिन सिम्लिंक का अंतिम लक्ष्य सिम्लिंक नहीं हो सकता है, अन्यथा हम अभी भी लिंक का अनुसरण कर सकते हैं और यह अंतिम लक्ष्य नहीं है। चूँकि इस तरह की कोई सहानुभूति नहीं है, हम उन्हें कुछ और के रूप में परिभाषित कर सकते हैं, अर्थात टूटी हुई सहानुभूति।
4

2
@ Joó Jodám "जो केवल एक प्रतीकात्मक लिंक हो सकता है अगर यह टूट गया है"। "टूटे हुए प्रतीकात्मक लिंक" या "गैर मौजूद फ़ाइल" को एक व्यक्तिगत प्रकार दें, ओवरलोडिंग के बजाय l, मेरे लिए कम भ्रमित नहीं है।
दुर्बल

3
अंत में चेतावनी उपयोगी है, लेकिन ध्यान दें कि यह -Lहैक पर लागू नहीं होता है, बल्कि (नेत्रहीन) सामान्य रूप से टूटे हुए सीमलिंक को हटा देता है।
एलोइस महदाल

38

symlinksसे आदेश http://www.ibiblio.org/pub/Linux/utils/file/symlinks-1.4.tar.gz विशेषताओं की एक किस्म के साथ सिमलिंक पहचान करने के लिए इस्तेमाल किया जा सकता। उदाहरण के लिए:

$ rm a
$ ln -s a b
$ symlinks .
dangling: /tmp/b -> a

क्या यह उपकरण ओएक्सएक्स के लिए उपलब्ध है?
क्लेड

कोई बात नहीं, संकलित कर लिया।
ज्यूड

2
जाहिरा तौर symlinksपर फेडोरा पर पहले से स्थापित है।
डैनियल जोंसन

32

जैसा कि rozcietrzewiacz ने पहले ही टिप्पणी की है, find -Lखोज को सहानुभूति वाली निर्देशिकाओं में विस्तारित करने का अप्रत्याशित परिणाम हो सकता है, इसलिए यह इष्टतम दृष्टिकोण नहीं है। जो किसी ने अभी तक उल्लेख नहीं किया है, वह है

find /path/to/search -xtype l

अधिक संक्षिप्त है, और तार्किक रूप से समान आदेश है

find /path/to/search -type l -xtype l

अब तक प्रस्तुत किए गए समाधानों में से कोई भी चक्रीय सीलिंक का पता नहीं लगाएगा, जो कि एक और प्रकार का टूटना है। यह सवाल पोर्टेबिलिटी को संबोधित करता है। संक्षेप में, चक्रीय लिंक सहित टूटे हुए प्रतीकात्मक लिंक को खोजने का पोर्टेबल तरीका है:

find /path/to/search -type l -exec test ! -e {} \; -print

अधिक जानकारी के लिए, यह प्रश्न या ynform.org देखें । बेशक, इस सब के लिए निश्चित स्रोत है डॉक्यूमेंट्स डॉक्यूमेंटटन


1
लघु, व्यंजन, और find -Lचक्रीय के साथ-साथ चक्रीय लिंक को संबोधित करता है । +1
13

अच्छा लगा। पिछले एक MacOSX पर भी काम करता है, जबकि @ rozcietrzewiacz का जवाब नहीं था।
neu242

1
@ neu242 संभावना है कि क्योंकि -xtypePOSIX में निर्दिष्ट नहीं है और वास्तव में यदि आप macOS में देखते हैं लेकिन find(1)यह नहीं है-type -xtype
प्रीफटन

7

मुझे विश्वास है कि -Lआपके आदेश में ध्वज जोड़ने से आप grep से छुटकारा पा सकते हैं:

$ find -L . -type l

http://www.commandlinefu.com/commands/view/8260/find-broken-symlinks

आदमी से:

 -L      Cause the file information and file type (see stat(2)) returned 
         for each symbolic link to be those of the file referenced by the
         link, not the link itself. If the referenced file does not exist,
         the file information and type will be for the link itself.

19
पहले तो मैंने इसे बढ़ा दिया है, लेकिन फिर मुझे एहसास हुआ कि यह कितना खतरनाक हो सकता है। इससे पहले कि आप इसका उपयोग करें, कृपया मेरे उत्तर पर एक नज़र डालें !
रोज़ज़ेट्रिएवेज़ेज़

6

यदि आपको एक अलग व्यवहार की आवश्यकता है कि क्या लिंक टूट गया है या चक्रीय है तो आप खोज के साथ% Y का उपयोग कर सकते हैं:

$ touch a
$ ln -s a b  # link to existing target
$ ln -s c d  # link to non-existing target
$ ln -s e e  # link to itself
$ find . -type l -exec test ! -e {} \; -printf '%Y %p\n' \
   | while read type link; do
         case "$type" in
         N) echo "do something with broken link $link" ;;
         L) echo "do something with cyclic link $link" ;;
         esac
      done
do something with broken link ./d
do something with cyclic link ./e

यह उदाहरण इस पोस्ट (हटाए गए साइट) से कॉपी किया गया है

संदर्भ


फिर भी उन लोगों के लिए एक और आशुलिपि जिसका findसमर्थन नहीं करता है xtype, इस से लिया जा सकता है find . type l -printf "%Y %p\n" | grep -w '^N':। जैसा कि एंडी ने मुझे अपनी स्क्रिप्ट में उसी (मूल) विचार के साथ हराया, मैं इसे अलग उत्तर के रूप में लिखने के लिए अनिच्छुक था। :)
वाक्यविन्यास

2

मैं अपने मामले के लिए इसका उपयोग करता हूं और यह काफी अच्छी तरह से काम करता है, क्योंकि मुझे पता है कि टूटी हुई सीमलिंक को देखने के लिए निर्देशिका है:

find -L $path -maxdepth 1 -type l

और मेरे फ़ोल्डर में एक लिंक शामिल है, /usr/shareलेकिन यह इसे पार नहीं करता है। क्रॉस-डिवाइस लिंक और जो कि chroots के लिए मान्य हैं, आदि अभी भी एक नुकसान हैं लेकिन मेरे उपयोग के मामले के लिए यह पर्याप्त है।


2

सरल न-ब्रेनर उत्तर, जो ओपी के संस्करण पर भिन्नता है। कभी-कभी, आप बस कुछ आसान टाइप या याद रखना चाहते हैं:

find . | xargs file | grep -i "broken symbolic link"

1

find -L . -type l |xargs symlinks आपको यह जानकारी देगा कि लिंक प्रति आधार पर मौजूद है या नहीं।


1

यह वर्तमान निर्देशिका में टूटे हुए सिमलिंक के नामों का प्रिंट आउट लेगा।

for l in $(find . -type l); do cd $(dirname $l); if [ ! -e "$(readlink $(basename $l))" ]; then echo $l; fi; cd - > /dev/null; done

बैश में काम करता है। अन्य गोले के बारे में पता नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.