जगह-जगह हार्ड-लिंक तोड़ना?


13

मैं अपने डॉटफ़ाइल्स को संस्करण नियंत्रण में रख रहा हूं और उन्हें तैनात करने वाली स्क्रिप्ट कठिन लिंक बनाती है। मैं etckeeperअपने /etcअंडर वर्जन कंट्रोल को रखने के लिए भी उपयोग करता हूं । हाल ही में मैंने इस तरह की चेतावनी दी है:

warning: hard-linked files could cause problems with bzr

एक साधारण प्रति ( cp filename.ext filename.ext) काम नहीं करेगी:

cp: `filename.ext' and `filename.ext' are the same file

एक फ़ाइल का नामकरण / स्थानांतरित करना - वॉल्यूम को छोड़कर - हार्ड-लिंक को भी नहीं तोड़ता है।

तो मेरा सवाल यह है: क्या वास्तव में यह जानने के बिना किसी फ़ाइल के हार्ड-लिंक को तोड़ने का एक तरीका है जहां उस फ़ाइल का अन्य हार्ड-लिंक / एस है / हैं?


2
"Rm" कमांड हार्ड लिंक को तोड़ती है।
जोहान

जवाबों:


14
cp -p filename filename.tmp
mv -f filename.tmp filename

इसे स्क्रिप्ट योग्य बनाना:

dir=$(dirname -- "$filename")
tmp=$(TMPDIR=$dir mktemp)
cp -p -- "$filename" "$tmp"
mv -f -- "$tmp" "$filename"

कॉपी को पहले करना, फिर उसे जगह में ले जाना, इसका फायदा यह है कि फाइल एटॉमिकली हार्ड लिंक होने से बदलकर एक अलग कॉपी हो जाती है (समय का कोई मतलब नहीं है जहां filenameआंशिक या गायब है)।


7

आपका शायद मतलब है कि आप हार्ड-लिंक को एक अलग, स्वतंत्र फ़ाइल में विभाजित करना चाहते हैं।

mv hardlink tempname && cp tempname hardlink && rm tempname

हार्डलिंक निर्देशिका में एक प्रविष्टि और डिस्क पर इनकोड ब्लॉक के बीच संबंध है।

इनकोड्स स्टोर फ़ाइल मेटा-डेटा, और छोटी फ़ाइलों के लिए, कुछ फ़ाइल सिस्टम इनकोड में डेटा स्टोर करते हैं, अन्यथा डेटा ब्लॉक पर पॉइंटर्स, और डिस्क आवंटन इकाइयों के लिए पॉइंटर्स की अप्रत्यक्ष और डबल-इनडायरेक्ट लिस्ट के लिए।

बावजूद, फ़ाइल नाम (जो कि ls कमांड का उत्पादन होता है) और इनोड ब्लॉक जो इस मेटा-डेटा को स्टोर करता है, के बीच संबंध को एक कड़ी कहा जाता है।

किसी एकल फ़ाइल के लिए कई हार्ड लिंक होने का मतलब है एक ही इनोड से संदर्भित एक से अधिक निर्देशिका प्रविष्टि, संभवतः विभिन्न निर्देशिकाओं में (एकल फ़ाइल पर)

rm निर्देशिका से फ़ाइल नाम प्रविष्टि को हटाता है। एक बार जब एक इनकोड को किसी भी फाइल द्वारा संदर्भित नहीं किया जाता है, तो इसका स्थान अन्य फ़ाइलों द्वारा उपयोग के लिए मुक्त हो जाता है।


वास्तव में। यह cpऔर mvउदाहरण निहित है। तो कोई रास्ता नहीं एक अस्थायी फ़ाइल का उपयोग करने के लिए, मैं देख रहा हूँ।
0xC0000022L

@ 0xC0000022L, नहीं, इनोड्स में अन्य इनोड्स के संकेत नहीं हैं। बस डेटा ब्लॉक (या यदि ऑब्जेक्ट छोटा है तो वे डेटा स्पेस के रूप में दोगुना कर सकते हैं)।
वॉनब्रांड

4
सुनिश्चित करें कि कॉपी करते समय अनुमतियाँ और अन्य डेटा संरक्षित है, अर्थात। उपयोग cp -a(कम से कम GNU कोरुटिल्स)।
वॉनब्रांड

@ 0xC0000022L, यदि आप ध्यान से देखें, तो मूल फ़ाइल के लिए सिर्फ एक अस्थायी नाम है, एक नई फ़ाइल केवल अंतिम चरण में बनाई गई है।
वॉनब्रांड

@vonbrand वे वास्तव में, किस फ़ाइल सिस्टम का उपयोग किया जा रहा है पर निर्भर करता है।
जोहान

4

इसे अपनी ~ / .bashrc फ़ाइल के अंत में रखें।

delink () { tmpfile="$1$(date)"; cp -a "$1" "$tmpfile"; mv "$tmpfile" "$1"; }

इसे ऐसे चलाओ

delink filename

3

बैश स्क्रिप्ट के साथ इसे करने का सबसे अच्छा तरीका कुछ इस तरह होगा:

if [ -f "$1" ] ; then
dir="$(dirname -- "$1")"
tmpfile="$(mktemp --tmpdir="$dir")"
cp --preserve=all -f -- "$1" "$tmpfile"
mv -f -- "$tmpfile" "$1"
fi

नोट करने के लिए अंक:

  • जाँच करें कि क्या फ़ाइल को कॉपी करने की कोशिश करने से पहले एक नियमित फ़ाइल है
  • जब तक कॉपी तैयार न हो जाए तब तक पुरानी फाइल को संभाल कर रखें
  • mktempएक फ़ाइल है जो मौजूद नहीं है की गारंटी देने के लिए उपयोग करें
  • -fअधिलेखित --preserve=allकरने के लिए और मूल फ़ाइल के लिए मेटाडेटा को यथासंभव रखने के लिए उपयोग करें
  • रिक्त स्थान और / या से युक्त पथों का उपयोग करना --और "उद्धरण करना-

अस्थायी फ़ाइल बनाने के बिना प्रतिस्थापन करना वर्तमान (3.16) लिनक्स सिस्टम कॉल के साथ संभव नहीं है: जबकि यह संभव है कि किसी फ़ाइल को परमाणु से अधिलेखित करना संभव है (अर्थात, पुरानी फ़ाइल को हटा दें और एक एकल ऑपरेशन के रूप में एक नए के साथ बदल दें), यह ऐसा किसी फ़ाइल के साथ करना संभव नहीं है, जिसका फाइल सिस्टम पर कोई नाम नहीं है (यानी एक अस्थायी फ़ाइल O_TMPFILEजो openफ़ंक्शन के ध्वज का उपयोग करके बनाई गई है ) क्योंकि renameफ़ंक्शन को इनपुट के रूप में फ़ाइल नाम की आवश्यकता होती है (कोई संस्करण नहीं है renameजो इनपुट फ़ाइल विवरणक के रूप में लेता है - देखने के लिए यहाँ जानकारी के लिए)


1
ध्यान दें कि आप अपने dirnameऔर mktempकॉल में नाम उद्धृत करने में विफल रहे । फिक्स्ड है कि आप के लिए ...
derobert

@derobert ओह, धन्यवाद, लेकिन यह काम नहीं करेगा क्योंकि नेस्टेड डबल कोट्स हैं ... एक और फिक्स की आवश्यकता है!
किन्दा

3
यह $( ... )-स्टाइल कमांड प्रतिस्थापन के कारण काम करेगा । एक कारण इसकी अच्छा-से- ` ... `शैली।
derobert

@derobert अच्छा, यह नहीं जानता था। इसके अलावा, आप इनलाइन इनलाइन टैग्स का उपयोग कैसे कर सकते हैं?
pqnet

आप उन्हें बैकस्लैश से बच सकते हैं। तो `आप में डाल पाने के लिए : `\``(बेशक, मैं दोगुना बच गया कि यह पाने के लिए कि आप क्या टाइप करते हैं)।
व्युत्पन्न

-1

वह कमांड जिसे आप ढूंढ रहे हैं unlink


शायद मेरा सवाल स्पष्ट नहीं था, लेकिन "इन-प्लेस" और उदाहरणों के साथ cpऔर mvमेरा मतलब स्पष्ट था कि मैं फ़ाइल को आगे की ओर मौजूद होना चाहता हूं।
0xC0000022L

आह, मुझे वह स्पष्ट नहीं मिला, नहीं। आपको जोहान के जवाब के साथ जाना चाहिए।
जेनी डी

1
कमांड "अनलिंक" बस फाइल को हटा देता है (अनलिंक () सिस्टम कॉल क्या करता है)।
राउल सालिनास-मोंटेगुडो

-1

यदि आप उन सभी फ़ाइलनामों को ढूंढ रहे हैं जो इस फ़ाइल में हार्डलिंक हैं तो आप उपयोग कर सकते हैं:

find -samefile myknowhardlinkfile

ls -il myknowhardlinkfileआपको उसी इनोड (तीसरे क्षेत्र) में हार्डलाइन किए गए फ़ाइल नाम की संख्या भी दिखाई देगी।

101612442 -rw-rw-r--. 2 me me 0 Aug  5 07:07 myknowhardlinkfile

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