एक फ़ोल्डर के भीतर सभी हार्डलिंक को तोड़ें


10

मेरे पास एक फ़ोल्डर है जिसमें कुछ निश्चित संख्या में फाइलें होती हैं जिनके हार्ड लिंक होते हैं (उसी फ़ोल्डर में या कहीं और), और मैं इन फ़ाइलों को डी-हार्ड करना चाहता हूं, इसलिए वे स्वतंत्र हो जाते हैं, और उनकी सामग्री में परिवर्तन किसी को प्रभावित नहीं करेगा। अन्य फ़ाइल (उनकी लिंक संख्या 1 हो जाती है)।

नीचे, मैं एक समाधान देता हूं जो मूल रूप से प्रत्येक हार्ड लिंक को किसी अन्य स्थान पर कॉपी करता है, फिर इसे वापस जगह पर ले जाता है।

हालाँकि यह तरीका कच्चा और त्रुटि-रहित प्रतीत होता है, इसलिए मैं जानना चाहूंगा कि क्या कुछ कमांड है जो मेरे लिए एक फाइल को डी-हार्डिंक करेगा।

कठोर जवाब:

वे फ़ाइलें ढूंढें जिनमें हार्ड लिंक हैं ( संपादित करें : सॉकेट आदि को खोजने के लिए जिनके पास हार्डलिंक हैं, उपयोग करें find -not -type d -links +1):

find      -type f -links +1 # files only
find -not -type d -links +1 # files, sockets etc.

किसी फ़ाइल को डी-हार्डिंक करने के लिए एक क्रूड विधि (इसे किसी अन्य स्थान पर कॉपी करें, और इसे वापस ले जाएं): संपादित करें: जैसा कि सेलाडा ने कहा, टाइमस्टैम्प और अनुमतियों को खोने से बचाने के लिए, नीचे एक cp -p करना सबसे अच्छा है। संपादित करें: एक अस्थायी निर्देशिका बनाएं और इसके तहत एक फ़ाइल में कॉपी करें, एक अस्थायी फ़ाइल को अधिलेखित करने के बजाय, यह कुछ डेटा को अधिलेखित करने के लिए जोखिम को कम करता है, हालांकि mvकमांड अभी भी जोखिम भरा है (धन्यवाद @Tobu)। संपादित करें: एक ही फाइल सिस्टम (@MikkoRantalainen) में अस्थायी निर्देशिका बनाने का प्रयास करें

# This is unhardlink.sh
set -e
for i in "$@"; do
  temp="$(mktemp -d -- "${i%/*}/hardlnk-XXXXXXXX")"
  [ -e "$temp" ] && cp -ip "$i" "$temp/tempcopy" && mv "$temp/tempcopy" "$i" && rmdir "$temp"
done

तो, करने के लिए संयुक्त राष्ट्र-hardlink सभी हार्ड लिंक ( संपादित करें : बदल -type fकरने के लिए -not -type d, ऊपर देखें):

find -not -type d -links +1 -print0 | xargs -0 unhardlink.sh

मैं उस 'क्रूड' पर विचार नहीं करूंगा। एकमात्र तरीका यह है कि तेजी से संभवत: सेंडफाइल () सिस्टम कॉल के साथ कुछ ट्रिक कर रहा है और ओपन सोर्स फाइल को अनलिंक कर रहा है और टारगेट को इन-प्लेस कर रहा है। सच कहूँ तो इसके प्रयास के लायक नहीं है।
मैथ्यू इफ

'क्रूड' से मेरा मतलब है कि, उदाहरण के लिए, जब मैंने इस कमांड को cp -iस्विच का उपयोग करके चलाया , तो इसने मुझे कुछ संदेश भेजे, जिसमें पूछा गया कि क्या यह ओवरराइड ./fileXXXXXX( $tempफाइल) होना चाहिए, भले ही tmpfile को यूनिक फाइल नेम देना चाहिए, इसलिए वहाँ होना चाहिए किसी तरह की दौड़ की स्थिति या जो भी हो, और इसके साथ कुछ डेटा को ढीला करने का जोखिम।
सुजैन डुपरॉन

1
यह सामान्य है कि फ़ाइल मौजूद है, आपने इसे केवल tempfile (nb: mktemp के पक्ष में पदावनत किया है, लेकिन यह आपकी समस्या का कारण नहीं है)।
तोबू

1
आपकी unhardlink.shउसी निर्देशिका के अंदर अस्थायी निर्देशिका बनानी चाहिए जिसमें वह फ़ाइल हो जिसमें अनहेल्दी होना आवश्यक है। अन्यथा आपकी पुनरावर्ती कॉल किसी अन्य फाइल सिस्टम के अंदर पुन: प्राप्त हो सकती है और आप फाइलसिस्टम सीमाओं पर सामान ले जाना समाप्त कर सकते हैं क्योंकि आपकी अस्थायी निर्देशिका वर्तमान कार्यशील निर्देशिका में है। मुझे लगता है कि आप "$(dirname "$i")/hardlink-XXXXXX"इसके बजाय mktemp के तर्क के रूप में पारित कर सकते हैं ।
मिकको रैंटलैनेन

1
@MikkoRantalainen बहुत बहुत धन्यवाद, अद्यतन! ध्यान दें कि यदि फाइलसिस्टम कुछ प्रकार के यूनियनफॉस् या fuseफाइलसिस्टम है, तो यह वास्तव path/to/hardlink-XXXमें एक अलग भौतिक भंडारण माध्यम से प्रेषण कर सकता है path/to/original-file, लेकिन इसके बारे में बहुत कुछ नहीं किया जा सकता है।
सुजैन डुपरॉन

जवाबों:


9

आपकी स्क्रिप्ट में सुधार के लिए जगह है, उदाहरण के -pलिए cpकमांड में एक विकल्प जोड़ना ताकि अनुमतियाँ और टाइमस्टैम्प को अनहार्डलिंक ऑपरेशन में संरक्षित किया जा सके, और आप कुछ त्रुटि से निपटने को जोड़ सकते हैं ताकि त्रुटि के मामले में अस्थायी फ़ाइल को हटा दिया जाए, लेकिन आपके समाधान का मूल विचार केवल वही है जो काम करेगा। किसी फ़ाइल को अनहाइडलिंक करने के लिए आपको उसे कॉपी करना होगा और फिर कॉपी को मूल नाम पर वापस ले जाना होगा। कोई "कम क्रूड" समाधान नहीं है, और इस समाधान में दौड़ की स्थिति है अगर एक और प्रक्रिया उसी समय फ़ाइल तक पहुंच रही है।


वास्तव में, मैं हमेशा cp -a का उपयोग सामान की नकल करते समय, सब कुछ संरक्षित करने के लिए करता हूं, पुन: व्यवस्थित करता हूं और सिम्बलिंक के रूप में कॉपी करता हूं। न जाने क्यों मैं इसे इस बार भूल गया था, लेकिन आपके उत्तर को देखने के बाद, मैंने समझा कि मैंने अपने सभी टाइमस्टैम्प को खराब कर दिया था, और उन्हें (बल्कि दर्दनाक रूप से) एक बैकअप से पुनर्प्राप्त करना था।
सुजैन डुपरॉन

5

यदि आप डिस्क स्थान को जलाना चाहते हैं, और आपके पास अपेक्षाकृत आधुनिक संस्करण है tar(जैसे, Ubuntu 10.04 और CentOS 6 पर), तो आप --hard-dereferenceविकल्प के साथ खेल सकते हैं ।

कुछ इस तरह:

$ cd /path/to/directory
$ ls -l *
bar:
total 12
-rw-rw-r-- 2 cjc cjc 2 May  6 19:07 1
-rw-rw-r-- 2 cjc cjc 2 May  6 19:07 2
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 3

foo:
total 12
-rw-rw-r-- 2 cjc cjc 3 May  6 19:07 1
-rw-rw-r-- 2 cjc cjc 2 May  6 19:07 2
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 4

(जहां मैं चला था ln foo/[12] bar)

$ tar cvf /tmp/dereferencing.tar --hard-dereference .
$ tar xvf /tmp/dereferencing.tar
$ ls -l *
bar:
total 12
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 1
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 2
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 3

foo:
total 12
-rw-rw-r-- 1 cjc cjc 3 May  6 19:07 1
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 2
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 4

मैन पेज से:

   --hard-dereference
          follow hard links; archive and dump the files they refer to

मुझे संदेह है कि बहुत कम टार नहीं हो सकता है। अच्छा तय किया।
जोसेफ कर्ण

मैं यह उल्लेख करना भूल गया कि मेरे पास सब कुछ कॉपी करने के लिए पर्याप्त डिस्क स्थान नहीं है। मूल रूप से, आपकी विधि वैसी ही है cp -a --no-preserve=links /path/to/folder /path/to/copy && rm -rf /path/to/folder && mv /path/to/copy /path/to/folder, जैसे कि मुझसे कोई गलती नहीं है। मुझे लगता है कि आपका तरीका अधिक कुशल होगा, हालांकि, क्योंकि टार में डिस्क डिस्क कम होती है, इसलिए थ्रैशिंग कम होती है। कोई भी rsync के साथ समान प्राप्त कर सकता है, cp विधि से भी कम प्रदर्शन के साथ :)।
सुजैन डुपरॉन

1
बहुत अधिक डिस्क का उपयोग करने से बचने के लिए, कुछ चलाना संभव हो सकता है tar cvf - --hard-dereference . | tar xf -लेकिन दौड़ की स्थिति हो सकती है जिससे चीजें विस्फोट हो जाएंगी। मैंने इसे करने की कोशिश नहीं की है, और मैं इस समय ऐसा करने के लिए विनिवेश कर रहा हूं।
ccc
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.