एक निर्देशिका को इंगित करने के लिए सिम्प्लिंक बनाने के लिए मैं कौन सी बेतुकी कमांड का उपयोग कर सकता हूं?


16

मैं एक शेल स्क्रिप्ट में एक कमांड डालना चाहता हूं, जो डायरेक्टरी के लिए एक सिमलिंक बनाएगा, लेकिन इस स्क्रिप्ट को बार-बार चलाया जा सकता है, इसलिए बाद के इनवोकेशन पर, कमांड को कुछ भी नहीं बदलना चाहिए।

यहाँ निर्देशिका संरचना है:

% tree /tmp/test_symlink 
/tmp/test_symlink
├── foo
└── repo
    └── resources
        └── snippets
            ├── php.snippets
            ├── sh.snippets
            ├── snippets.snippets
            ├── sql.snippets
            └── vim.snippets

मैं foo/स्निपेट्स नामक एक सिम्प्लेक्स बनाना चाहता हूं जो निर्देशिका को इंगित करता है /tmp/test_symlink/repo/resources/snippets
तो मैं चला:

% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets' -> '/tmp/test_symlink/repo/resources/snippets'

जो वांछित परिणाम देता है।

% tree /tmp/test_symlink                                                          
/tmp/test_symlink
├── foo
   └── snippets -> /tmp/test_symlink/repo/resources/snippets
└── repo
    └── resources
        └── snippets
            ├── php.snippets
            ├── sh.snippets
            ├── snippets.snippets
            ├── sql.snippets
            └── vim.snippets

5 निर्देशिका, 5 फाइलें

हालाँकि, जब आदेश फिर से चलाया जाता है,

% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets/snippets' -> '/tmp/test_symlink/repo/resources/snippets'

यह एक डायरेक्टरी के लिए एक सिम्लिंक बनाता है, जहां सिमलिंक एल्डी मौजूद है, सिम्लिंक को वास्तविक डायरेक्टरी के अंदर रखता है

% tree /tmp/test_symlink                                                          
/tmp/test_symlink
├── foo
   └── snippets -> /tmp/test_symlink/repo/resources/snippets
└── repo
    └── resources
        └── snippets
            ├── php.snippets
            ├── sh.snippets
            ├── snippets -> /tmp/test_symlink/repo/resources/snippets
            ├── snippets.snippets
            ├── sql.snippets
            └── vim.snippets

ऐसा क्यों हो रहा है और मैं कमांड को कैसे संशोधित कर सकता हूं ताकि बाद के इनवोकेशन इस अजीब प्रभाव को पैदा न करें?

जवाबों:


16

आपको इसके लिए -Tविकल्प का उपयोग करना चाहिए , यह बताता हैln हमेशा लिंक नाम को वांछित लिंक नाम के रूप में मानता है, कभी निर्देशिका के रूप में नहीं।

इस विकल्प के बिना, यदि आप lnएक लिंक नाम देते हैं जो एक निर्देशिका के रूप में मौजूद है, तो यह उस निर्देशिका के अंदर लक्ष्य के लिए एक नया लिंक बनाता है।

ध्यान दें कि -Tएक GNU-ism है (कम से कम, यह POSIX में नहीं है), लेकिन आप पहले से ही उपयोग कर रहे हैं -vजो कि एक GNU-ism है इसलिए मुझे लगता है कि यह एक मुद्दा नहीं है।

वैकल्पिक रूप से, आप केवल लिंक नाम के रूप में मूल निर्देशिका निर्दिष्ट कर सकते हैं, और लिंक हमेशा (पुनः) वहाँ बनाया जाएगा:

ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/

यह काम करता है क्योंकि आपके सिम्लिंक का लक्ष्य के समान नाम है।


धन्यवाद, हां ग्नू विकल्प जरूरी पोर्टेबल नहीं हैं, लेकिन वे वास्तव में उपयोगी हो सकते हैं - जब पोर्टेबिलिटी की आवश्यकता नहीं है। आपका जवाब मेरे लिए काम करता है। मैन पेज से -n, --no-dereference treat LINK_NAME as a normal file if it is a symbolic link to a directory-T, --no-target-directory treat LINK_NAME as a normal file alwaysक्या आपको लगता है कि सिम्लिंक को हमेशा फ़ाइल के रूप में व्यवहार करना बेहतर है? मैंने सोचा होगा कि इन "विशेष" विकल्पों के उपयोग को सीमित करना बेहतर होगा?
the_velour_fog

यदि आप जानते हैं कि वे उपलब्ध हैं, तो GNU- विशिष्ट विकल्पों (IMO) से बचने का कोई कारण नहीं है। आपने एक idempotent कमांड के लिए कहा, -Tयह है कि आप lnidempotent कैसे बनाते हैं । यदि आप चाहें तो परिणाम प्राप्त करने के अन्य तरीके भी हैं, जैसे लिंक को हटाना और फिर से बनाना, या यदि आप जानते हैं कि fooपहले से मौजूद है, ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/(वास्तव में यह एक बेहतर उत्तर हो सकता है, तो मैं अपडेट करूंगा)।
स्टीफन किट

1
शांत, हाँ, मैं पहले से ifसिमलिंक की उपस्थिति का पता लगाने के लिए बयानों का उपयोग कर रहा था और अगर सिम्कलिन मौजूद था, तो कमांड को छोड़ सकता हूं, लेकिन स्क्रिप्ट समाप्त हो जाती है और पढ़ने में मुश्किल होती है, मैं कुछ सुखद लेकिन सरल के लिए जा रहा था, जैसे कि आपके mkdir -pपरीक्षण का उपयोग करना , कोई तर्क नहीं, सिर्फ अच्छे ओएल एक लाइनर्स :)
the_velour_fog 7

@ स्टीफन किट: आपने -T के उपयोग का उल्लेख किया है, लेकिन मैं इसे आपके उत्तर के कोड स्निपेट में नहीं ढूंढ सका। क्या मैं गलत समझ रहा हूँ या कुछ याद कर रहा हूँ?
Guizmoo03

@ Guizmoo03 शायद आप "वैकल्पिक रूप से" चूक गए जो स्निपेट का परिचय देता है। पहले तीन पैराग्राफ समझाते हैं -T, लेकिन मेरे जवाब का अंत एक और समाधान प्रस्तुत करता है जो उपयोग नहीं करता है -T
स्टीफन किट

-1

सबसे अच्छा मैं बता सकता हूं कि यहां क्या हो रहा है कि दूसरी पास पर lnकमांड ऐसा व्यवहार करता है cpया mv, जो यह है कि अगर यह <गंतव्य पर "निर्देशिका" देखता है तो यह फ़ाइल को इसके अंदर डाल देगा, अन्यथा अगर <गंतव्य> नहीं है मौजूद है, यह <गंतव्य> बना देगा। (जो कि "स्लैशडॉट" चाल से बचा जाता है - यानी यह सुनिश्चित करेगा कि <गंतव्य> मौजूद है और एक निर्देशिका है)।
लेकिन मुझसे गलती हो सकती है।

किसी भी स्थिति में यह काम करने लगता है

ln -sfv --no-dereference /tmp/test_symlink/repo/resources/snippets/ foo/snippets
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.