व्यस्त बॉक्स में कोई भी सहानुभूति को एक निर्देशिका में कैसे बदल सकता है?


18

मैं (संभवतः के रूप में करीब के रूप में) की कोशिश कर रहा हूँ atomically एक सिमलिंक बदलें। मैंने कोशिश की:

ln -sf other_dir existing_symlink

इसने उस नई सिम्लिंक को केवल उस निर्देशिका में रखा, जिसे मौजूदा_सिमलिंक ने इंगित किया है।

ln -sf other_dir new_symlink
mv -f new_symlink existing_symlink

यही काम किया: इसने सिम्लिंक को डायरेक्टरी में स्थानांतरित कर दिया।

cp -s other_dir existing_symlink

यह मना कर देता है क्योंकि यह एक निर्देशिका है।

मैंने पढ़ा है कि mv -Tइसके लिए बनाया गया था, लेकिन व्यस्त बॉक्स में -Tझंडा नहीं है ।

जवाबों:


1

मैं यह नहीं देखता कि आप परमाणु संचालन कैसे कर सकते हैं। अगर यह लक्ष्य पहले से मौजूद symlink(2)है, EEXISTतो मैन पेज कहता है। यदि कर्नेल परमाणु संचालन का समर्थन नहीं करता है, तो आपकी उपयोगकर्ता सीमाएँ अप्रासंगिक हैं।

मैं यह भी नहीं देखता कि कैसे mv -Tमदद करता है, भले ही आपके पास यह हो। इसे नियमित लिनक्स बॉक्स पर आज़माएं, GNU mv के साथ:

$ mkdir a b
$ ln -s a z
$ mv -T b z
mv: cannot overwrite non-directory `z' with directory `b'

मुझे लगता है कि आप इसे दो चरणों में करने जा रहे हैं: पुराने सिम्लिंक को हटा दें और इसे फिर से बनाएँ।


1
वास्तव में, दुर्भाग्यवश कोई ऐसा तरीका नहीं है जिससे आप प्रतीकात्मक रूप से परमाणु को संशोधित कर सकते हैं। सबसे अच्छा आप कर सकते हैं पुराने लिंक को हटा दें और एक नया बनाएं। GNU कोरुटिल्स के पास एक एकल कमांड ( ln -snf) के साथ ऐसा करने का विकल्प है , लेकिन हुड के तहत अभी भी दो सिस्टम कॉल हैं।
गिल्स एसओ- बुराई को रोकना '

43

यह कर सकते हैं वास्तव में साथ atomically किया जाना rename(2)है, पहले एक अस्थायी नाम के तहत नए सिमलिंक बनाने और फिर सफाई से एक ही बार में वर्ष सिमलिंक ओवरराइट करके। जैसा कि मैन पेज बताता है:

यदि newpath एक प्रतीकात्मक लिंक को संदर्भित करता है तो लिंक को ओवरराइट कर दिया जाएगा।

शेल में, आप इसे mv -Tनिम्नानुसार करेंगे:

$ mkdir a b
$ ln -s a z
$ ln -s b z.new
$ mv -T z.new z

आप straceयह सुनिश्चित कर सकते हैं कि यह वास्तव rename(2)में हुड के नीचे उपयोग कर रहा है:

$ strace mv -T z.new z
lstat64("z.new", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
lstat64("z", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
rename("z.new", "z")                    = 0

नोट ऊपर में है कि, दोनों mv -Tऔर straceकर रहे हैं लिनक्स विशिष्ट।

FreeBSD पर, mv -hवैकल्पिक रूप से उपयोग करें ।


1
बहुत अच्छा! यह कहना मददगार हो सकता है कि अंत में आपके पास z से b तक एक लिंक हो!
विन्केन्जो पीआई

ओएस-स्वतंत्र समाधान के लिए एक स्क्रिप्टिंग भाषा का उपयोग करें जो renameसीधे syscall का उपयोग करने के बजाय mv -hया इसके लिए सक्षम है mv -T। पर्ल के साथ उदाहरण के लिए:perl -e 'rename "z.new", "z" or die $!'
स्लावेन रेज़िक

8

आर्टो को यहां छोड़ दिया जाना, यह पूरी तरह से संभव है, यहां तक ​​कि इसके बिना भी mv -T, आपको बस एक नई सिमिलिंक बनाने की जरूरत है, जिसका नाम लक्ष्य निर्देशिका है और mvयह आपके लक्ष्य की मूल निर्देशिका में है:

mkdir -p tmp/real_dir1 tmp/real_dir2
touch tmp/real_dir1/a tmp/real_dir2/a
# start with ./target_dir pointing to tmp/real_dir1
ln -s tmp/real_dir1 target_dir
# create a symlink named target_dir in tmp, pointing to real_dir2
ln -sf tmp/real_dir2 tmp/target_dir
# atomically mv it into ./ replacing ./target_dir
mv tmp/target_dir ./

कोड उदाहरण ( http://axialcorps.wordpress.com/2013/07/03/atomically-replacing-files-and-directories/ ) के माध्यम से लिया गया


3

क्या आपने कोशिश की है ln -snf?

विकल्प -nगंतव्य के लिए एक प्रतीकात्मक लिंक होने पर उसके नीचे लिखने के बजाय गंतव्य को ओवरराइट करता है।

चियर्स


3
ln -snfपरमाणु नहीं है: यह गंतव्य को अनलिंक करता है, फिर वांछित सिमिलिंक बनाता है।
गिलेस एसओ- बुराई को रोकना '

2
यह देखते हुए कि ओपी को "सिमी के रूप में बदलने के लिए" कब्जे के रूप में पास होने में दिलचस्पी थी [ई], यह पूरी तरह से उचित जवाब है। यदि एक बेहतर है जो परमाणु के करीब (या हो सकता है), तो वह स्वीकार किया जा सकता है। मुझे नहीं लगता कि डाउनवोट की जरूरत है।
विल्को ऑक्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.