मुझे अपना प्रतीकात्मक लिंक खोजने के लिए 'रियलपैथ' कैसे मिलेगा?


13

मैं bashअपने खोल के रूप में उपयोग कर MacOSX पर हूँ । मेरे पास प्रतीकात्मक लिंक है, इस तरह बनाया गया है:

ln -s /usr/bin/python python2 

मेरे पास एक पैकेज है जो python2 का उपयोग करता है और मैं अपनी वर्तमान कार्य निर्देशिका में एक प्रतीक लिंक बनाना चाहता हूं /usr/bin/pythonजो वास्तव में python2 है। जब मैं python2कमांड लाइन से करता हूं तो मुझे यह त्रुटि मिलती है:

python2: realpath couldn't resolve "/usr/bin/python2"

लेकिन इसे इस तरह से लागू करना ./python2सही ढंग से पथ को हल करता है। मेरा PATHइसमें .है। वास्तव में मैंने इसे संशोधित किया है, परीक्षण के लिए, केवल .इसमें है।

मैं इसका कैसे समाधान करूं? धन्यवाद!


प्रसंग

नीचे दिए गए समाधानों की एक संख्या मेरे लिए काम नहीं करेगी। मैंने अपने प्रश्न को यथासंभव ध्यान केंद्रित करने और संक्षिप्त करने की कोशिश की ताकि लोग पाठ के समुद्र में न डूबें, लेकिन स्पष्ट रूप से मुझे अधिक पृष्ठभूमि प्रदान करने की आवश्यकता है।

मैं एक पैकेज पर विकसित करने की कोशिश कर रहा हूं जिसे मैंने गिट से क्लोन किया है। मूल पैकेज, git-multimailलिनक्स के कुछ प्रकार पर विकसित किया गया है / है (मैं उबंटू का अनुमान लगा रहा हूं)। मैं इसे संशोधित करने की कोशिश कर रहा हूं कि इसका और MacOSX पर इसके परीक्षण सूट का उपयोग करने में सक्षम हो सके। यहाँ कुछ प्रस्तावित समाधान आदर्श क्यों नहीं हैं:

  1. रूट के रूप में, python2/ usr / bin / में एक सिमलिंक बनाएँ । मैं एक ऐसे समाधान की तलाश कर रहा हूं जिसके लिए इसकी आवश्यकता नहीं होगी। यह शुरुआत में एक स्पष्ट विकल्प था, लेकिन मैं एक ऐसा समाधान चाहूंगा जो मेजबान प्रणाली को यथासंभव कम संशोधित करे। यही कारण है कि मैं वर्तमान वर्किंग डायरेक्टरी में एक अस्थायी सिमलिंक बनाना चाहता था, CWD (यानी .) को मेरे पथ में जोड़ें, और तब समाप्त होने पर इसे नष्ट कर दें (यानी सिमलिंक)।

  2. मौजूदा अजगर के साथ अजगर स्क्रिप्ट को कॉल करने के लिए एक आवरण स्क्रिप्ट बनाएं। इसके साथ समस्या यह है कि सही निष्पादन वातावरण खोजने के लिए शेब पर निर्भर परीक्षण सूट के अधिकांश वास्तविक स्क्रिप्ट_ निष्पादन योग्य के रूप में उपयोग करता है। इसका मतलब होगा कि परीक्षण सूट का संपादन काफी हद तक। इस संदर्भ में, (परीक्षण-रूपरेखा के एक स्निपेट के लिए नीचे देखें), मुझे हर .pyफ़ाइल के लिए एक आवरण जोड़ना होगा ; इसके अलावा उपयोगकर्ता / डेवलपर को पैकेज के उपयोग के लिए अलग-अलग नियमों के बारे में पता होना चाहिए कि वे किस प्रणाली पर हैं (यानी MacOSX पर सुनिश्चित करें कि आप रैपर फ़ाइलों को रैपर या स्पष्ट रूप से कॉल करने के बिना उपयोग नहीं करते हैं /usr/bin/python file.py)।

    #! /bin/sh
    
    D=$(cd $(dirname "$0") && pwd)
    MULTIMAIL="$D/../git-multimail/git_multimail.py"
    POST_RECEIVE="$D/../git-multimail/post-receive"
    
    TESTREPO=$("$D/create-test-repo")
    
    HOME="$D"
    XDG_CONFIG_HOME="$D"
    GIT_CONFIG_NOSYSTEM=1
    export HOME XDG_CONFIG_HOME GIT_CONFIG_NOSYSTEM
    
    cd $TESTREPO
    
    test_email() {
        REFNAME="$1"
        OLDREV="$2"
        NEWREV="$3"
        echo "$OLDREV" "$NEWREV" "$REFNAME" | USER=pushuser "$MULTIMAIL"
    
    } 
  3. सभी python2संदर्भों को बदलना pythonREADME यह सुझाव देता है, लेकिन यह प्रभावी रूप से संस्करण नियंत्रण को बेकार बनाता है क्योंकि सिस्टम परिवर्तन को नए संस्करण के रूप में देखता है, जब वास्तव में यह (शब्दार्थ) नहीं है।

मैं (3) का उपयोग कर रहा हूं, लेकिन मैं एक बेहतर समाधान खोजने की कोशिश कर रहा हूं। मैं यह स्वीकार करने को तैयार हूं कि यह सिर्फ चीजें हैं (यानी 'python2' को इंगित करने का उपयुक्त तरीका नहीं है /usr/bin/pythonकि परीक्षण सूट और वास्तविक ढांचे में बहुत सारे बदलावों के बिना पोर्टेबल और विनीत है)।


1
अरे! बसln -s /usr/bin/python /usr/bin/python2
enedil

वास्तव में मैं लिनक्स पर git-multimail विकसित करता हूं। लेकिन मैं OS X. BTW पर काम करने के लिए पैच और परीक्षकों का स्वागत करता हूं, आपका "python2" मुद्दा अब हल हो गया है, क्योंकि git-multimail python2 और python3 :-) दोनों को स्वीकार करता है।
मैथ्यू मोय

विस्तारित प्रश्न अभी भी एक महत्वपूर्ण विवरण याद कर रहा है: निष्पादन योग्य लिपियों में शबंग रेखा क्या दिखती है? के लिए git-multimail.pyयह है #!/usr/bin/env python2, इसलिए वहाँ एक (अपेक्षाकृत) सीधा तरीका यह है है।
एलेक्सिस

@ enedil की टिप्पणी से काम नहीं चला, फिर ln -s /usr/bin/python2.7 /usr/local/bin/python2भी
फ्य्लिडा

जवाबों:


3

यदि आपको एक सिमलिंक को हल करने (या जांचने) की आवश्यकता है तो आप प्लेटफ़ॉर्म स्वतंत्र बैश लाइब्रेरी 'realpath-lib' का उपयोग कर सकते हैं। डिफ़ॉल्ट रूप से यह रीडलिंक का अनुकरण करता है और मैक या यूनिक्स पर काम करेगा। यह Github या Bitbucket पर पाया जा सकता है और यह मुफ़्त है।

लेकिन ऐसा लगता है कि आप अपने स्थानीय (कामकाजी) निर्देशिका से सिर्फ python2 (बल्कि ./python2) करना चाहते हैं। यह आपके .bashrc में एक उपनाम के साथ ऐसा करना संभव हो सकता है या अन्यथा आपको अपने PATH पर्यावरण चर में काम करने वाली निर्देशिका (जिसमें आपका सिमलिंक होता है) को जोड़ना होगा। यह वर्तमान सत्र के लिए या भविष्य के सत्रों के लिए .bashrc फ़ाइल के भीतर भी किया जा सकता है। यह सिर्फ एक विशिष्ट उपयोगकर्ता के लिए एक समाधान हो सकता है।

एक अन्य विकल्प जो सभी उपयोगकर्ताओं के लिए काम करेगा, वह पथ पर किसी अन्य निर्देशिका में / usr / bin / python को python2 symlink बनाने के लिए होगा, जैसे / usr / local / bin में कहेंगे। शायद कुछ इस तरह:

sudo ln -s /usr/bin/python /usr/local/bin/python2

फिर किसी भी उपयोगकर्ता या स्क्रिप्ट को अजगर या python2 कमांड ढूंढनी चाहिए। बेशक इस विकल्प को स्थापित करने के लिए व्यवस्थापक (रूट) विशेषाधिकारों की आवश्यकता होती है।


मैंने आखिरकार हार मान ली। बहुत सी जगहें हैं जो कोड में 'python2' मानती हैं और हर स्थानीय समाधान में सभी संभावनाओं को शामिल नहीं किया गया है। यह इस नाखून के लिए सबसे उपयुक्त स्लेजहैमर है।
एवरी चैन

@ सब, क्या तुमने मेरे समाधान की कोशिश की? क्या कोई समस्या थी? यह जोड़ने के लिए आवश्यक नहीं होता python2करने के लिए /usr/bin(हालांकि मैं एक सुधार के रूप में जोड़ने देखने, ईमानदार होना करने के लिए)।
एलेक्सिस

यह एक उपनाम (...) के साथ ऐसा करना संभव हो सकता है क्योंकि उपनाम केवल कमांड लाइन को प्रभावित करता है और स्क्रिप्ट नहीं। देखें कि डेबियन 7.5 में पायथन के डिफ़ॉल्ट संस्करण को कैसे बदला जाए?
पायोटर डोब्रोगोस्ट

यह सही उत्तर नहीं है, कम से कम यह समस्या को हल नहीं करता है जिसने पोस्टर को सवाल पूछने के लिए प्रेरित किया।
smaudet

16

मेरा मानना ​​है कि आप एक ही कार्यक्रम के कई संस्करणों के बीच प्रबंधन और स्विचन के लिए Apple के सिस्टम से दूर चल रहे हैं। आप जो चाहते हैं उसे पूरा कर सकते हैं, कम सुरुचिपूर्ण ढंग से, लेकिन समस्याओं के बिना, निम्न स्क्रिप्ट नाम के साथ python2:

#!/bin/bash
exec /usr/bin/python "$@"

इसे निष्पादन योग्य बनाएं ( chmod +x python2), और आप व्यवसाय में हैं।

समस्या की व्याख्या:

जब आप दौड़ते हैं /usr/bin/python, तो यह python2.7 उसी डायरेक्टरी में पाया और निष्पादित होता है। आपका प्रतीकात्मक लिंक विफल हो जाता है क्योंकि सिस्टम सिमलिंक का अनुसरण करता है /usr/bin, फिर खोजता है और वहां खोजने में विफल रहता है python2 । आप प्रतीकात्मक लिंक के बजाय "हार्ड लिंक" का उपयोग करके एक कदम आगे बढ़ सकते हैं:

rm python2
ln /usr/bin/python python2

अब अनुसरण करने के लिए कोई प्रतीकात्मक लिंक नहीं है, एक ही फ़ाइल (इनोड) के लिए सिर्फ दो फ़ाइल नाम। लेकिन अब मैं निम्नलिखित संदेश के साथ विफल रहा:

python2: posix_spawn: /Users/alexis/.../python22.7: No such file or directory

सूचना python22.7: फ्रेमवर्क 2.7आपके द्वारा बनाए गए नाम से जुड़ रहा है! इसके बजाय इसे अनसुना करने की कोशिश करने और लिंक का एक जंगल स्थापित करने के लिए जो इसकी अपेक्षाओं से मेल खाता है, मैं आपको सलाह देता हूं कि आप संस्करण प्रबंधन ढांचे के रास्ते से बाहर रहें, और ऊपर सुझाए गए समाधान का उपयोग करें।

पुनश्च। एक बेहतर समाधान हो सकता है: यदि आप बताएंगे कि आपको शुरू करने के लिए क्या करने की आवश्यकता है (आपको इसके लिए python2एक उपनाम के रूप में प्रदान करने की आवश्यकता क्यों है python), तो कोई व्यक्ति संभवतः इसे अलग तरीके से करने में आपकी सहायता कर सकता है। इसे स्टैकएक्सचेंज लिंगो में एक "XY समस्या" के रूप में जाना जाता है ...


जब आप दौड़ते हैं /usr/bin/python, तो यह उसी निर्देशिका में python2.7 को ढूंढता और कार्यान्वित करता है। यह बहुत भ्रामक कथन है। यदि आप उस मामले का वर्णन करते हैं जहां /usr/bin/pythonएक सिमलिंक है तो कृपया अधिक विशिष्ट हो।
पिओट्र डोब्रोगोस्ट

यह आश्चर्यजनक रूप से बुरा है ..
निकोलस

आश्चर्यजनक रूप से क्या बुरा है?
एलेक्सिस

हाँ, यहाँ स्पष्ट रूप से उल्लेख नहीं किया गया है कि मुझे लगता है कि usr / usr / bin / python वास्तव में अजगर नहीं है, यह सिर्फ MacOS स्थापित अजगर (python2.7 जिसे फ्रेमवर्क फ़ोल्डर में सिमिलिंक किया गया है) दिखता है। मुझे संदेह है कि @nicolas कह रहा है कि नकली अजगर संस्करण आश्चर्यजनक खराब है - यह काफी हैक है और मेरी इच्छा है कि Apple ने ऐसा नहीं किया था। ... कई चीजें हैं जो मैं चाहता हूं कि ऐप्पल ने ऐसा नहीं किया जो कि उनके अन्यथा ठीक यूनिक्स सिस्टम को ठीक कर देता है।
smaudet


1

readlinkएक लिंक भौतिक पथ का पता लगाने के लिए आप यूनिक्स कमांड का उपयोग कर सकते हैं ।

उदाहरण

कहो मेरे पास निम्न लिंक है:

$ ls -l /usr/bin/etags
lrwxrwxrwx. 1 root root 29 Dec 10 22:56 /usr/bin/etags -> /etc/alternatives/emacs.etags

$ ls -l /etc/alternatives/emacs.etags
lrwxrwxrwx. 1 root root 20 Dec 10 22:56 /etc/alternatives/emacs.etags -> /usr/bin/etags.ctags

$ ls -l /usr/bin/etags.ctags
lrwxrwxrwx. 1 root root 5 Dec 10 22:56 /usr/bin/etags.ctags -> ctags

  1. मूल्य को खोजने के लिए एक प्रतीकात्मक लिंक इंगित करता है

    $ readlink /usr/bin/etags
    /etc/alternatives/emacs.etags

    नोट: उपरोक्त परिणाम एक और लिंक हो सकता है। इसे हल करने के लिए नीचे # 2 देखें।

  2. मूल्य के निरपेक्ष पथ का पता लगाने के लिए एक प्रतीकात्मक लिंक इंगित करता है

    $ readlink -f /usr/bin/etags
    /usr/bin/ctags

0

मुझे समझ नहीं आ रहा है - यह कैसे माना जाता है कि एक रैपर लिंक ठीक है, लेकिन एक रैपर स्क्रिप्ट नहीं है ? या तो एक अप्रत्यक्ष स्तर है। और क्या आपको अभी भी अपने उपयोगकर्ताओं को केवल एक निश्चित निर्देशिका से कॉल करने के लिए निर्देश नहीं देना होगा?

किसी भी मामले में, आप निश्चित रूप से वर्तमान कार्यशील निर्देशिका प्राप्त कर सकते हैं $PATH:

 echo "echo \"Hi! I'm python\"" >|./python 
 chmod +x ./python 
 PATH="${PWD}:${PATH}" 
 python

 #OUTPUT#
 Hi! I'm python

 rm python 
 python -V 
 ln -s /usr/bin/python2 ./python 
 python -V

 #OUTPUT#
 Python 3.4.0
 Python 2.7.6

 PATH="${PATH#"${PWD}:"}" 
 python -V

 #OUTPUT#
 Python 3.4.0

कृपया लाओ । अपने से बाहर $PATH। यह एक भयानक विचार है।


.मेरे $ PATH में एक बुरा विचार क्यों है ? अगर मैं इसे अंत में रख दूं, तो जो आखिरी जगह दिखाई देगी, वह मेरी वर्तमान कार्यशील निर्देशिका है (यानी `पैथ =" $ {पाथ}: $ {पीडब्ल्यूडी} "। एक रैपर स्क्रिप्ट का अर्थ है कि हर अजगर फ़ाइल के लिए। एक अतिरिक्त फ़ाइल बनाना है। अजगर के निष्पादन के लिए एक आवरण लिंक बस मुझे करने के लिए एक चीज बनाता है
Avery Chan

@AveryChan मुझे ऐसा नहीं लगता। एक आवरण स्क्रिप्ट एक शेल फ़ंक्शन या अन्य नाम स्रोत कर सकती है जो निष्पादन योग्य के समान नाम के साथ है। यह --bind mountवर्तमान निर्देशिका में निष्पादन योग्य भी हो सकता है (या केवल linux, मुझे लगता है) chrootआवश्यक के रूप में भी । परंतु । में $PATHके लिए काम करता है किसी भी निर्देशिका और विशिष्ट नहीं है। यह आपके उपयोगकर्ताओं के लिए खतरनाक है। किसी भी मामले में, मैंने बहुत स्पष्ट रूप से दिखाया कि यह कैसे करना है। क्या यह आपकी आवश्यकताओं को पूरा नहीं करता है?
mikeserv

0

Re @alexis उत्तर, अजगर संस्करण /usr/binअसली अजगर नहीं है।

यह तीन तरीकों से स्पष्ट होना चाहिए:

  1. जो त्रुटि हमें मिल रही है, वह वह नहीं है जो अजगर आमतौर पर पैदा करता है। अजगर का व्यवहार एक और अजगर की तलाश में नहीं है, इसकी अजगर की स्क्रिप्ट को निष्पादित करने के लिए है।

  2. यदि आप /usr/bin/pythonऔर वास्तव में python2.7 के शमस की गणना करते हैं, जो चलाया जाता है:

shasum /usr/bin/python
3782d9ab14b35037c9c7fb665439a5fa695c54a6  /usr/bin/python
shasum /usr/bin/python2.7
476fa96c80ac26a85b2d3b01ddfd19e513660c2c  /usr/bin/python2.7

वे पूरी तरह से अलग हैं। इसके अतिरिक्त, फ़ाइल का आकार ~ 20k बाइट्स से भिन्न होता है:

ll /usr/bin/python
-rwxr-xr-x  1 root  wheel  66880 May 17  2019 /usr/bin/python

बनाम

ll /System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
-rwxr-xr-x  1 root  wheel  43104 May 17  2019 /System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
  1. अंत में, आप अजगर 2.7 और अजगर को विघटित कर सकते हैं और प्रतीकों की जांच कर सकते हैं। हालांकि 'ऑस्कर पर python2 को python2 करने के लिए सिम्पीलिंग कैसे करें' के दायरे से थोड़ा बाहर है।

इसलिए (जैसा कि त्रुटि इंगित करता है) /usr/bin/pythonचारों ओर मुड़ता है और दिखता है /usr/bin/python2.7:

ll /usr/bin/python2.7
lrwxr-xr-x  1 root  wheel  75 Jul  1  2019 /usr/bin/python2.7 -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7

यही कारण है कि निम्नलिखित कार्य (शिष्टाचार @ लिआंगमिन-ली का उत्तर):

    ln -s /System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /usr/local/bin/python2

साइट पर आपका स्वागत है। आप अपने नमूना lsआउटपुट से देखने के बारे में कुछ स्पष्टीकरण जोड़ना चाह सकते हैं जो कि /usr/bin/python"वास्तविक अजगर नहीं है"।
एडमिन

इसका स्पष्ट रूप से स्पष्ट रूप से उल्लेख है, लेकिन मैं अपडेट कर सकता हूं कि हम इसे कैसे निर्धारित कर सकते हैं।
smaudet

यह किसी ऐसे व्यक्ति के लिए हो सकता है जो एक विशिष्ट pythonदुभाषिया बाइनरी के आकार को जानता है , लेकिन याद रखें कि यहां उत्तर अधिक सामान्य यू एंड एल दर्शकों के लिए उपयोग किए जाने योग्य हैं ...
व्यवस्थापन

1
मैंने अपना नमूना अपडेट कर दिया है। हालांकि, बाइनरी पहचान को साबित करना एक कठिन समस्या है, यही वजह है कि मैं पूरी तरह से यह नहीं बताता हूं कि यहां (आकार संस्करणों के बीच वैध रूप से भिन्न हो सकते हैं, व्यवहार बदल सकते हैं - जैसा कि मैंने अपने अद्यतन उत्तर में पोस्ट किया है सबूत यह है कि यह प्रणाली कैसे व्यवहार करती है बनाम कैसे एक वेनिला पायथन इंस्टॉलेशन को माना जाता है। मुझे नहीं लगता है कि रिवर्स इंजीनियरिंग के बारे में एक जवाब अजगर बाइनरी उचित होगा या वास्तव में यहाँ सहायक होगा)। लेकिन मैं आपकी बात समझ गया।
smaudet
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.