सिम्लिंक का केवल गंतव्य खोजें


50

शेल-स्क्रिप्ट में उपयोग के लिए, मैं एक प्रतीकात्मक लिंक के गंतव्य को प्राप्त करने के लिए कमांडलाइन-तरीका ढूंढ रहा हूं। मैं अब तक सबसे करीब आया हूं stat -N src, जो आउटपुट है src -> dst। बेशक मैं आउटपुट को पार्स कर सकता था और प्राप्त कर सकता था dst, लेकिन मुझे आश्चर्य है कि क्या गंतव्य प्राप्त करने का कोई सीधा तरीका है।

जवाबों:


61

एक अन्य विकल्प विशेष रूप से तैयार कमांड का उपयोग करना होगा readlinkयदि उपलब्ध हो।

उदाहरण के लिए

$ readlink -f `command -v php`
/usr/bin/php7.1

21
का प्रयोग करें readlink -fअगर आप जानना चाहते हैं पिछले सिमलिंक लक्ष्य और न केवल अगले एक।
स्काइ

अच्छी बात! भूल गए।
निकितातु

11
ध्यान दें कि -fGNU में एक गैर-पोर्टेबल एक्सटेंशन है readlink
बहमट

2
रीडिंक कब उपलब्ध नहीं होगा? धन्यवाद।
tommy.carstensen

2
@ tommy.carstensen रीडलिंक (1) को 2003 में GNU Coreutils में जोड़ा गया था, इसलिए इन दिनों आप संभावित रूप से coreutils का उपयोग कर सभी प्रणालियों पर निर्भर कर सकते हैं। (Cf. git.savannah.gnu.org/cgit/coreutils.git/commit/src/… )
रोडिन

16

Mac OS X और FreeBSD / NetBSD / etc पर। आईटी इस:

stat -f %Y <filename>

अधिक सामान्य रूप से मुझे लगता है कि समाधान है (स्टेट - प्रिंटफ =% एन अजीब उद्धरण का उपयोग करता है):

ls -l b | sed -e 's/.* -> //'

उदाहरण:

# ln -s a b
# stat -f %Y b
a

एक अन्य विधि है:

# find b -maxdepth 0 -printf %l
a#

अंतिम पंक्ति को मंगाई गई है क्योंकि इसमें कोई नई रेखा नहीं है, लेकिन यह ठीक है अगर आपको चर में परिणाम की आवश्यकता है, जैसे

# f=$(find b -maxdepth 0 -printf %l)
# echo $f
a

-maxdepthको रोकने के लिए की जरूरत है findनिर्देशिका में उतरते से अगर bएक निर्देशिका होता है।


मैंने पूरी तरह से स्किम्ड किया, stat --printf='%N\n'ठीक वही है जो मैं चाहता हूं, अजीब उद्धरण मुझे परेशान नहीं करते हैं, वही उद्धरण आरएम और एलएन
इन

यह स्पष्ट रूप से पोर्टेबल नहीं है क्योंकि लिनक्स पर, जीएनयू कोरुटिल्स स्टेट (1) link -> destके आउटपुट में अलग-अलग पैरामीटर और प्रिंट हैं । खोज (1) समाधान की जाँच की जानी चाहिए अगर यह GNU खोजक या अन्य के साथ है ...
जोसिप रॉडिन

कृपया अपने वैरिएबल के विस्तार को उद्धृत करना न भूलें, echo $fनिश्चित रूप से वह नहीं पैदा करता है जो आप उम्मीद करते हैं जब सिमलिंक इंगित करता है /*(हाँ यह संभव है)
कैमुसेंसी

3

यह जीएनयू उपयोग किया जा सकता find: find src -prune -printf "%l\n"


1

आंशिक रूप से: ls -l आउटपुट, या उपयोग पार्स करने के लिए heuristics का उपयोग करने के अलावा कोई भाग्य नहीं है perl -le 'print readlink("some-file")'

कुछ सिस्टम में एक readlinkकमांड होती है, कुछ -fको पूर्ण पथ प्राप्त करने के विकल्प के साथ ।

/ सिस्टम कॉल के statलिए एक आवरण के रूप में एक कमांड के विभिन्न कार्यान्वयन हैं। जीएनयू एक उस लिहाज से उपयोगी नहीं है, लेकिन ज़ीश का बिलियन वन अधिक है:statlstat

zmodload zsh/stat
stat +link the-link

अभी भी zsh के साथ, आप एक फ़ाइल का पूर्ण पथ प्राप्त कर सकते हैं (हर सिम्कलिन घटक को हटा देता है) :Aसंशोधक के साथ (चर विस्तार, इतिहास विस्तार और ग्लोबिंग पर लागू होता है:

~$ gstat -c %N b
`b' -> `a'
~$ var=b
~$ echo $var:A
/home/me/a
~$ echo b(:A)
/home/me/a
~$ echo ?(@:A)
/home/me/a

1

ऐसी प्रणाली पर जहां मेरे पास कोई आदेश readlinkया statआदेश नहीं है, लेकिन मेरे पास पायथन 2.x है, मैं एक छोटी स्क्रिप्ट का उपयोग कर रहा हूं:

#!/usr/bin/env python

import os, sys

if __name__ == "__main__":
    src = sys.argv[1]
    target = os.readlink(src)
    if not os.path.isabs(target):
            target = os.path.abspath(os.path.join(os.path.dirname(src), target))
    print target

ध्यान दें कि इसके विपरीत readlink -fकेवल एक स्तर के सिमलिंक का अनुसरण किया जा सकता है।


1

पोर्टेबल शुद्ध बैश realpath

bash_realpath() {
  # print the resolved path
  # @params
  # 1: the path to resolve
  # @return
  # &1: the resolved link path

  local path="${1}"
  while [[ -L ${path} && "$(ls -l "${path}")" =~ -\>\ (.*) ]]
  do
    path="${BASH_REMATCH[1]}"
  done
  echo "${path}"
}

0

realpathcoreutilsपैकेज की कमान ,

जैसा कि readlinkकमांड के मैनुअल पेज में लिंक किया गया है।


उदाहरण के लिए:

realpath /bin/python

आउटपुट

/usr/bin/python2.7

मेरी मशीन पर।

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