আমি কীভাবে ম্যাকের সাথে জিএনইউ'র রিডলিংক-এর আচরণ পেতে পারি?


376

লিনাক্সে, readlinkইউটিলিটি একটি বিকল্প গ্রহণ করে -fযা অতিরিক্ত লিঙ্কগুলি অনুসরণ করে। এটি ম্যাক এবং সম্ভবত বিএসডি ভিত্তিক সিস্টেমে কাজ করছে বলে মনে হচ্ছে না। সমতুল্য কি হবে?

এখানে কিছু ডিবাগ তথ্য রয়েছে:

$ which readlink; readlink -f
/usr/bin/readlink
readlink: illegal option -f
usage: readlink [-n] [file ...]

1
কিছুটা দেরি হয়ে গেছে, তবে আপনার প্রশ্নে আপনার ব্যবহৃত শেলটির কোনও উল্লেখ নেই। এটি প্রাসঙ্গিক, কারণ readlinkএকটি বিল্টিন বা বাহ্যিক আদেশ হতে পারে।
0xC0000022L

1
এটি সম্ভবত পার্থক্য ব্যাখ্যা করবে। আমি নিশ্চিত যে আমি উভয় অনুষ্ঠানে ব্যাশ ব্যবহার করেছি।
troelskn

1
ম্যাক্সে এই বিকল্পটি কেন অবৈধ?
কমাটোস্ট

3
আমি সত্যিই আশা করি অ্যাপল ওএস এক্সকে আরও ডিফল্ট লিনাক্স পাথ তৈরি করবে এবং এর মতো জিনিসগুলিকে সম্বোধন করবে। তারা কিছু না ভেঙে এটি করতে পারে, তাই না?
কমাটোস্ট

1
@ কমমাটোস্ট ওয়েল, তারা পার্লের সাথে ++ :-) চালান ... টার্মিনাল.এপ খুলুন এবং টাইপ করুন: touch myfile ; ln -s myfile otherfile ; perl -MCwd=abs_path -le 'print abs_path readlink(shift);' otherfile... আমার ক্ষেত্রে আমি দেখতে পাচ্ছি: / ব্যবহারকারী / সিটো / মাইফাইল` ` এটি নীচে আমার প্রতিক্রিয়া এ যুক্ত। চিয়ার্স।
জি সিটো

উত্তর:


181

readlink -f দুটি কাজ করে:

  1. এটি আসল ফাইল খুঁজে না পাওয়া পর্যন্ত এটি সিমলিঙ্কগুলির ক্রম ধরে পুনরাবৃত্তি করে।
  2. এটি সেই ফাইলটির ক্যানোনিকালাইজড নাম returns অর্থাত্ এটির সম্পূর্ণ নাম path

আপনি যদি চান, আপনি কেবল একটি শেল স্ক্রিপ্ট তৈরি করতে পারেন যা একই জিনিসটি অর্জন করতে ভ্যানিলা রিডলিঙ্ক আচরণ ব্যবহার করে। এখানে একটি উদাহরণ। স্পষ্টতই আপনি এটি নিজের স্ক্রিপ্টে সন্নিবেশ করতে পারেন যেখানে আপনি কল করতে চানreadlink -f

#!/bin/sh

TARGET_FILE=$1

cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`

# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]
do
    TARGET_FILE=`readlink $TARGET_FILE`
    cd `dirname $TARGET_FILE`
    TARGET_FILE=`basename $TARGET_FILE`
done

# Compute the canonicalized name by finding the physical path 
# for the directory we're in and appending the target file.
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$TARGET_FILE
echo $RESULT

মনে রাখবেন যে এতে কোনও ত্রুটি পরিচালনার অন্তর্ভুক্ত নেই। বিশেষ গুরুত্বের সাথে এটি সিমলিংক চক্র সনাক্ত করে না। এটি করার একটি সহজ উপায় হ'ল আপনি লুপটির চারপাশে কতবার যান এবং আপনি যদি অসম্ভব বড় সংখ্যায় যেমন 1,000 ব্যবহার করেন তবে ব্যর্থ হন।

pwd -Pপরিবর্তে ব্যবহার করতে সম্পাদনা করুন $PWD

লক্ষ্য করুন এই স্ক্রিপ্টের আশা মত বলা হবে ./script_name filename, কোন -fপরিবর্তন $1করার $2যদি তুমি চাও সঙ্গে ব্যবহার করার জন্য পাবে -f filenameমত গনুহ readlink।


1
আমি যতদূর বলতে পারি, পথের পিতামাতার দির যদি একটি সিমলিংক হয় তবে এটি কাজ করবে না। যেমন। যদি foo -> /var/cux, তবে এর foo/barসমাধান হবে না, কারণ barএটি কোনও লিঙ্ক নয়, যদিও foo
Troelskn

1
আহ। হ্যাঁ. এটি এতটা সহজ নয় তবে এটি মোকাবেলায় আপনি উপরের স্ক্রিপ্টটি আপডেট করতে পারেন। আমি সেই অনুযায়ী উত্তর সম্পাদনা করব (পুনরায় লিখুন, সত্যই)।
কিথ স্মিথ

ঠিক আছে, কোনও লিঙ্কটি যে কোনও জায়গায় থাকতে পারে। আমার ধারণা, স্ক্রিপ্টটি পথের প্রতিটি অংশে পুনরাবৃত্তি করতে পারে তবে এটি তখন কিছুটা জটিল হয়ে ওঠে।
Troelskn

1
ধন্যবাদ। সমস্যাটি হ'ল $ পিডাব্লুডি আমাদের লজিকাল ওয়ার্কিং ডিরেক্টরী দিচ্ছে, যা আমরা অনুসরণ করেছি সিমলিংকের মানগুলিতে। আমরা 'pwd -P' দিয়ে আসল শারীরিক ডিরেক্টরি পেতে পারি এটি ফাইল সিস্টেমের মূল পর্যন্ত ".." তাড়া করে এটি গণনা করা উচিত। আমি আমার উত্তরে সেই অনুযায়ী স্ক্রিপ্ট আপডেট করব।
কিথ স্মিথ

12
দুর্দান্ত সমাধান, তবে এটি এমবেডেড স্পেস সহ ফাইল বা ডিরেক্টরিগুলির নামের মতো পালানোর দরকারের পথে সঠিকভাবে মোকাবেলা করে না । প্রতিকার যে, ব্যবহার এবং এবং উপরে কোডে যথাযথ স্থানে। cd "$(dirname "$TARGET_FILE")"TARGET_FILE=$(readlink "$TARGET_FILE")TARGET_FILE=$(basename "$TARGET_FILE")
mklement0

438

ম্যাকপোর্টস এবং হোমব্রু একটি কোর্টিল প্যাকেজ সরবরাহ করে greadlink(জিএনইউ রিডলিংক)। ম্যাকবাল.কম এ মাইকেল কলভিট পোস্টে ক্রেডিট।

brew install coreutils

greadlink -f file.txt

আপনি যদি বাশ ব্যতীত অন্য স্থান থেকে রিডলিঙ্ককে কল দিচ্ছেন তবে অন্য সমাধান হ'ল / ইউএসআর / বিন / রিডলিংক হ'ল / ইউএসআর / স্থানীয় / বিন / গ্রিডলিংকের একটি লিঙ্ক তৈরি করুন।
চিংলুন

8
দয়া করে করবেন না, যদি না আপনি) ক) নিজের নিজের জন্য সফটওয়্যার লিখেন খ) অন্যদের সাথে গোলযোগ করতে চান না। এটিকে এমনভাবে লিখুন যে এটি কারও পক্ষে "স্রেফ কাজ করে"।
কেজিডেক

14
@ching এর পরিবর্তে এটি করুন আপনার .bashrc:export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
বিফোনটেন

1
প্রশ্নটি একটি ওএস এক্স বা বিএসডি সিস্টেমে সমতুল্যের জন্য জিজ্ঞাসা করে, এটি এর উত্তর দেয় না। আপনাকে হোমব্রুও ইনস্টল করতে হবে। আপনি জিএনইউ রিডলিংক ছাড়াও অনেকগুলি জিনিস ইনস্টল করবেন। আপনি যদি স্ট্যান্ডার্ড ওএস এক্স ইনস্টল করার জন্য কোনও স্ক্রিপ্ট লিখছেন তবে এই উত্তরটি কোনও সাহায্য করবে না। আপনি একটি সমন্বয় ব্যবহার করতে পারেন pwd -Pএবং readlink, OS X এর কিছু ইনস্টল না করে
জেসন এস

4
আমি চেয়েছিলেন আমার ম্যাক গনুহ এবং অন্যান্য utils যে আমি এত ভাল না বিশ্বাস করি, উপসর্গ ছাড়া, আর আমার ব্যবহারকারীর থেকে সহজে প্রবেশযোগ্য PATH। উপরের দিয়ে শুরু কি brew install <package> --default-names। অনেক সময় এই সাইটে কোনও প্রশ্নের সামান্য উত্তর দেওয়া হয়েছে বা আরও অনেক কিছু, প্রশ্নকারীর প্রযুক্তিগত প্রয়োজনীয়তার বাইরে, তবে একই পরিস্থিতিতে, এবং এখনও খুব সহায়ক হয়েছে। topbug.net/blog/2013/04/14/…
পিসিস

43

আপনি আগ্রহী হতে পারে realpath(3), বা পাইথন এর os.path.realpath। দুটি ঠিক এক নয়; সি লাইব্রেরি কলের জন্য মধ্যবর্তী পথের উপাদানগুলির উপস্থিতি থাকা দরকার, যখন পাইথন সংস্করণ নেই।

$ pwd
/tmp/foo
$ ls -l
total 16
-rw-r--r--  1 miles    wheel  0 Jul 11 21:08 a
lrwxr-xr-x  1 miles    wheel  1 Jul 11 20:49 b -> a
lrwxr-xr-x  1 miles    wheel  1 Jul 11 20:49 c -> b
$ python -c 'import os,sys;print(os.path.realpath(sys.argv[1]))' c
/private/tmp/foo/a

আমি জানি যে আপনি বলেছিলেন যে আপনি অন্য স্ক্রিপ্টিং ভাষার চেয়ে কিছু বেশি হালকা ওজনের চেয়ে পছন্দ করতে পারেন, তবে কেবল বাইনারি সংকলন অপ্রয়োজনীয়, আপনি লাইব্রেরির কলটি মোড়ানোর জন্য পাইথন এবং সিটিপস (ম্যাক ওএস এক্স 10.5 এ উপলব্ধ) ব্যবহার করতে পারেন:

#!/usr/bin/python

import ctypes, sys

libc = ctypes.CDLL('libc.dylib')
libc.realpath.restype = ctypes.c_char_p
libc.__error.restype = ctypes.POINTER(ctypes.c_int)
libc.strerror.restype = ctypes.c_char_p

def realpath(path):
    buffer = ctypes.create_string_buffer(1024) # PATH_MAX
    if libc.realpath(path, buffer):
        return buffer.value
    else:
        errno = libc.__error().contents.value
        raise OSError(errno, "%s: %s" % (libc.strerror(errno), buffer.value))

if __name__ == '__main__':
    print realpath(sys.argv[1])

হাস্যকরভাবে, এই স্ক্রিপ্টটির সি সংস্করণটি কম হওয়া উচিত। :)


হ্যাঁ, realpathসত্যিই আমি যা চাই এটি বরং বিশ্রী বলে মনে হচ্ছে শেল স্ক্রিপ্ট থেকে এই ফাংশনটি পেতে আমাকে একটি বাইনারি সংকলন করতে হবে।
ট্রলস্কে্ন

4
কেন তখন শেল স্ক্রিপ্টে পাইথন ওয়ান-লাইনার ব্যবহার করবেন না? ( readlinkনিজের কাছে এক লাইনের কল থেকে এতটা আলাদা না, তাই না?)
টেলিমাচাস

3
python -c "import os,sys; print(os.path.realpath(os.path.expanduser(sys.argv[1])))" "${1}"পাথগুলি নিয়ে কাজ করে'~/.symlink'
ওয়েস টার্নার

@ ট্রোলসকিন আমি পার্ল, পাইথন ইত্যাদি বুঝতে পারিনি "অনুমতিপ্রাপ্ত" !! ... perl -MCwd=abs_path -le 'print abs_path readlink(shift);'
সেক্ষেত্রে

27

আমি আর একটি বাস্তবায়ন দিয়ে গাদা করতে ঘৃণা করি, তবে আমার প্রয়োজন একটি) একটি বহনযোগ্য, খাঁটি শেল বাস্তবায়ন এবং খ) ইউনিট-পরীক্ষা কভারেজ , কারণ এর মতো কোনও কিছুর জন্য এজ-সংখ্যার সংখ্যা অ-তুচ্ছ

পরীক্ষা এবং সম্পূর্ণ কোডের জন্য গিথুবটিতে আমার প্রকল্প দেখুন । নিম্নলিখিতটি বাস্তবায়নের একটি সংক্ষিপ্তসার:

কীথ স্মিথ আশ্চর্যের সাথে উল্লেখ করেছেন, readlink -fদুটি কাজ করেছেন: 1) প্রতীকগুলি পুনরাবৃত্তভাবে সমাধান করে এবং 2) ফলাফলটি স্বীকৃতি দেয়, তাই:

realpath() {
    canonicalize_path "$(resolve_symlinks "$1")"
}

প্রথমত, সিমিলিংক রেজোলভার বাস্তবায়ন:

resolve_symlinks() {
    local dir_context path
    path=$(readlink -- "$1")
    if [ $? -eq 0 ]; then
        dir_context=$(dirname -- "$1")
        resolve_symlinks "$(_prepend_path_if_relative "$dir_context" "$path")"
    else
        printf '%s\n' "$1"
    fi
}

_prepend_path_if_relative() {
    case "$2" in
        /* ) printf '%s\n' "$2" ;;
         * ) printf '%s\n' "$1/$2" ;;
    esac 
}

দ্রষ্টব্য যে এটি সম্পূর্ণ বাস্তবায়নের সামান্য সরলীকৃত সংস্করণ । সম্পূর্ণ বাস্তবায়ন সিমলিংক চক্রের জন্য একটি ছোট চেক যুক্ত করে , পাশাপাশি আউটপুটকে কিছুটা ম্যাসেজ করে।

অবশেষে, কোনও পথকে আকাঙ্ক্ষিত করার জন্য ফাংশন:

canonicalize_path() {
    if [ -d "$1" ]; then
        _canonicalize_dir_path "$1"
    else
        _canonicalize_file_path "$1"
    fi
}   

_canonicalize_dir_path() {
    (cd "$1" 2>/dev/null && pwd -P) 
}           

_canonicalize_file_path() {
    local dir file
    dir=$(dirname -- "$1")
    file=$(basename -- "$1")
    (cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd -P)" "$file")
}

এটিই কমবেশি। আপনার স্ক্রিপ্টে পেস্ট করার জন্য যথেষ্ট সহজ, তবে যথেষ্ট কৌশলযুক্ত যে আপনি যে কোনও কোডে আপনার ব্যবহারের ক্ষেত্রে ইউনিট পরীক্ষা না করে তার উপর নির্ভর করতে উন্মাদ হবেন।


3
এটি local
পসিক্স

এটি এর সমতুল্য নয় readlink -f, নয় realpath। কোর্টিলস সূত্রটি ইনস্টল করা (যেমন greadlinkউপলব্ধ) এর সাথে একটি ম্যাক ধরে নিচ্ছেন , এটি দিয়ে চেষ্টা করুন ln -s /tmp/linkeddir ~/Documents; greadlink -f /tmp/linkeddir/..আপনার হোম ডিরেক্টরি মুদ্রণ করে (এটি প্যারেন্ট ডির রেফ /tmp/linkeddirপ্রয়োগ করার আগে লিঙ্কটি সমাধান করেছে ..), তবে আপনার কোডটি একটি সিমিলিংক /private/tmp/হিসাবে তৈরি করে /tmp/linkeddir/..না তবে -d /tmp/linkeddir/..এটি সত্য এবং তাই cd /tmp/linkeddir/..আপনাকে /tmpযাঁর আধ্যাত্মিক পথটি নিয়ে যায় /private/tmprealpath -Lপরিবর্তে আপনার কোডটি যা করে তা করে।
মার্টিজন পিটারস

27

পার্লের একটি সহজ ওয়ানলাইনার যা কোনও বাহ্যিক নির্ভরতা ছাড়াই প্রায় সর্বত্র কাজ করা নিশ্চিত:

perl -MCwd -e 'print Cwd::abs_path shift' ~/non-absolute/file

প্রতীকীকরণ symlinks হবে।

স্ক্রিপ্টের ব্যবহার এরকম হতে পারে:

readlinkf(){ perl -MCwd -e 'print Cwd::abs_path shift' "$1";}
ABSPATH="$(readlinkf ./non-absolute/file)"

4
একটি trailing সম্পর্কে newline পেতে, অ্যাড -lমত,perl -MCwd -le 'print Cwd::abs_path shift' ~/non-absolute/file
pjvandehaar

26
  1. হোমব্রু ইনস্টল করুন
  2. "ব্রিউ ইনস্টল কোরিউটিলস" চালান
  3. "গ্রেডলিঙ্ক -ফ পাথ" চালান

গ্রেডলিঙ্ক হ'ল gnu লিডিং লিঙ্ক যা প্রয়োগ করে -f। আপনি ম্যাকপোর্ট বা অন্যগুলিও ব্যবহার করতে পারেন, আমি হোমব্রু পছন্দ করি।



আপনার যদি এই কমান্ডগুলির সাধারণ নামগুলি ব্যবহার করার দরকার হয় তবে আপনি আপনার বাশার্ক থেকে আপনার প্যাথের জন্য একটি "গনুবিন" ডিরেক্টরি যুক্ত করতে পারেন যেমন: PATH = "/ usr / স্থানীয় / অপ্ট / কোর্টিলস / লিবেক্সেক / জেনুবিন: AT पथ"
ডেনিস ট্রোফিমভ

20

আমি ব্যক্তিগতভাবে রিয়েলপথ নামে একটি স্ক্রিপ্ট তৈরি করেছি যা দেখতে কিছুটা অল্প দেখাচ্ছে:

#!/usr/bin/env python
import os.sys
print os.path.realpath(sys.argv[1])

আপনি sys.argv[1]যদি স্ক্রিপ্টটি প্রথম আর্গুমেন্টের রিয়েলপথটি মুদ্রণ করতে চান তবে এটিতে আপনার পরিবর্তন করা উচিত । sys.argv[0]কেবল পাইটন স্ক্রিপ্টের আসল পথটি মুদ্রণ করে, যা খুব কার্যকর নয়।
Jakob Egger

17
~/.profilealias realpath="python -c 'import os, sys; print os.path.realpath(sys.argv[1])'"
এটির

দুর্দান্ত উত্তর, এবং দুর্দান্ত ওয়ান-লাইনার @ জেভিটলক। যেহেতু ওপি উদ্ধৃত হয়েছে readlink -f, এখানে সম্ভাব্য -fপতাকাটি সমর্থন করার জন্য @ জাভিটলকের উলামের একটি পরিবর্তিত সংস্করণ রয়েছে : alias realpath="python -c 'import os, sys; print os.path.realpath(sys.argv[2] if sys.argv[1] == \"-f\" else sys.argv[1])'"
কোডনিফার

11

এই সম্পর্কে কি?

function readlink() {
  DIR="${1%/*}"
  (cd "$DIR" && echo "$(pwd -P)")
}

এটি আমার জন্য একমাত্র সমাধান যা কাজ করে; আমাকে ../../../->/
কেফ্লাভিচ

সিস্টেমটি পছন্দ করতে /usr/bin/যেমন আপনার কাছে একটি সিমলিংক থাকে তবে এটি কাজ করতে পারে না alternatives
akostadinov

পৃথক ফাইলের জন্য কাজ করে না, কেবল ডিরেক্টরি। জিএনইউ রিডলিঙ্ক ডিরেক্টরি, ফাইল, সিমলিংক ইত্যাদির সাথে কাজ করে
কোডস্নিফ

7

এখানে একটি পোর্টেবল শেল ফাংশন যা কোনওটিতে কাজ করা উচিত বোর্ন তুলনীয় শেলটিতে । এটি আপেক্ষিক পথ বিরামচিহ্নগুলি সমাধান করবে ".. বা"। এবং সম্মান প্রতীকী লিঙ্ক।

যদি কোনও কারণে আপনার কাছে একটি রিয়েলপথ (1) কমান্ড না থাকে, বা পঠন লিঙ্ক (1) এটিকে বিকল্প দেওয়া যেতে পারে।

which realpath || alias realpath='real_path'

উপভোগ করুন:

real_path () {
  OIFS=$IFS
  IFS='/'
  for I in $1
  do
    # Resolve relative path punctuation.
    if [ "$I" = "." ] || [ -z "$I" ]
      then continue
    elif [ "$I" = ".." ]
      then FOO="${FOO%%/${FOO##*/}}"
           continue
      else FOO="${FOO}/${I}"
    fi

    ## Resolve symbolic links
    if [ -h "$FOO" ]
    then
    IFS=$OIFS
    set `ls -l "$FOO"`
    while shift ;
    do
      if [ "$1" = "->" ]
        then FOO=$2
             shift $#
             break
      fi
    done
    IFS='/'
    fi
  done
  IFS=$OIFS
  echo "$FOO"
}

এছাড়াও, কেবলমাত্র এখানে যে কেউ আগ্রহী তা হল 100% খাঁটি শেল কোডে কীভাবে বেসনাম এবং ডারনামটি প্রয়োগ করা যায়:

## http://www.opengroup.org/onlinepubs/000095399/functions/dirname.html
# the dir name excludes the least portion behind the last slash.
dir_name () {
  echo "${1%/*}"
}

## http://www.opengroup.org/onlinepubs/000095399/functions/basename.html
# the base name excludes the greatest portion in front of the last slash.
base_name () {
  echo "${1##*/}"
}

আপনি আমার গুগল সাইটে এই শেল কোডটির আপডেট সংস্করণ খুঁজে পেতে পারেন: http://sites.google.com/site/jdisnard/relpath

সম্পাদনা: এই কোডটি 2-ধারা (ফ্রিবিএসডি শৈলী) লাইসেন্সের শর্তাদির অধীনে লাইসেন্সযুক্ত। আমার সাইটের উপরের হাইপারলিঙ্ক অনুসরণ করে লাইসেন্সের একটি অনুলিপি পাওয়া যেতে পারে।


রিয়েল_পথ ব্যাশ শেলের মধ্যে ম্যাক ওএস এক্স লায়নটিতে / পাথ / থেকে / ফাইলের পরিবর্তে ফাইলের নাম / ফাইল নাম দেয় returns

@ ব্যারি ওএসএক্স স্নো চিতাবাঘে একই ঘটে happens সবচেয়ে খারাপ, রিয়েল_পথ () একের পর এক আউটপুট!
ডোমিনিক

@ ডমিনিক: অবাক করা কিছু নয়, যেহেতু ফাংশনের অভ্যন্তরটি নিজস্ব সাবশেলে চালিত হচ্ছে না ... সত্যই কুরুচিপূর্ণ এবং ভঙ্গুর।
0xC0000022L

7

ফ্রিবিএসডি এবং ওএসএক্সেরstat নেটবিএসডি থেকে প্রাপ্ত সংস্করণ রয়েছে ।

আপনি ফর্ম্যাট সুইচগুলির সাথে আউটপুট সামঞ্জস্য করতে পারেন (উপরের লিঙ্কগুলিতে ম্যানুয়াল পৃষ্ঠাগুলি দেখুন)।

%  cd  /service
%  ls -tal 
drwxr-xr-x 22 root wheel 27 Aug 25 10:41 ..
drwx------  3 root wheel  8 Jun 30 13:59 .s6-svscan
drwxr-xr-x  3 root wheel  5 Jun 30 13:34 .
lrwxr-xr-x  1 root wheel 30 Dec 13 2013 clockspeed-adjust -> /var/service/clockspeed-adjust
lrwxr-xr-x  1 root wheel 29 Dec 13 2013 clockspeed-speed -> /var/service/clockspeed-speed
% stat -f%R  clockspeed-adjust
/var/service/clockspeed-adjust
% stat -f%Y  clockspeed-adjust
/var/service/clockspeed-adjust

কিছু ওএস এক্স সংস্করণে ফর্ম্যাটের বিকল্পের stat অভাব থাকতে পারে -f%R। এই ক্ষেত্রে -stat -f%Yযথেষ্ট হতে পারে। -f%Yবিকল্প একটি সিমবলিক লিঙ্ক লক্ষ্য দেখাবে, যেহেতু-f%R শো পরম পথনাম ফাইল সংশ্লিষ্ট।

সম্পাদনা করুন:

আপনি যদি পার্ল ব্যবহার করতে সক্ষম হন (ডারউইন / ওএস এক্স এর সাম্প্রতিক ভার্শনগুলির সাথে ইনস্টল হয় perl) তবে:

perl -MCwd=abs_path -le 'print abs_path readlink(shift);' linkedfile.txt

কাজ করবে.


2
এটি ফ্রিবিএসডি 10 এ সত্য, তবে ওএস এক্স 10.9 এ নয়।
জাঞ্চে

ভালো বল ধরা. পরিসংখ্যান ম্যানুয়েল পৃষ্ঠা উদাহৃত ওএস / এক্স 10.9 জন্য। Rবিকল্পে -f%অনুপস্থিত। সম্ভবত stat -f%Yকাঙ্ক্ষিত আউটপুট দেয়। আমি উত্তরটি সামঞ্জস্য করব। দ্রষ্টব্য যে statসরঞ্জামটি FreeBSD সংস্করণে 4.10 সংস্করণ এবং নেটবিএসডি সংস্করণে 1.6 সংস্করণে উপস্থিত হয়েছিল।
জি সিটো

পার্ল কমান্ড 10.15 এ সঠিকভাবে কাজ করে না। এটি বর্তমান ডিরেক্টরিতে একটি ফাইল দিন এবং এটি বর্তমান ডিরেক্টরি দেয় (ফাইলটি ছাড়াই)।
কোডনিফার 18

7

এই সমস্যাটি সমাধান করার সহজ উপায় এবং ম্যাক ডাব্লু / হোমব্রিউ ইনস্টল করা বা ফ্রিবিএসডি-তে রিডলিংকের কার্যকারিতা সক্ষম করার জন্য 'কোর্টিলস' প্যাকেজ ইনস্টল করা। নির্দিষ্ট লিনাক্স বিতরণ এবং অন্যান্য পসিক্স ওএসেও প্রয়োজনীয় হতে পারে।

উদাহরণস্বরূপ, ফ্রিবিএসডি 11-তে, আমি অনুরোধ করে ইনস্টল করেছি:

# pkg install coreutils

হোমব্রিউ সহ ম্যাকওএসে কমান্ডটি হ'ল:

$ brew install coreutils

অন্যান্য উত্তরগুলি কেন এত জটিল তা সত্যই নিশ্চিত নয়, এগুলিতে কেবল এটি রয়েছে। ফাইলগুলি অন্য কোনও জায়গায় নেই, সেগুলি এখনও ইনস্টল করা হয়নি।


7
brew install coreutils --with-default-namesআরো নির্দিষ্ট করা. অথবা আপনি তার পরিবর্তে "গ্রিডলিঙ্ক" দিয়ে শেষ করবেন ...
হেন্ক

আমি 2010 এর stackoverflow.com/a/4031502/695671 এবং 2012 stackoverflow.com/a/9918368/695671 থেকে উত্তরগুলির মধ্যে কোনও পার্থক্য দেখতে পাচ্ছি না প্রশ্নটি আসলে "... ম্যাক এবং সম্ভবত বিএসডি ভিত্তিক সিস্টেমগুলিতে What সমতুল্য? " আমি বিশ্বাস করি না যে এটি এই প্রশ্নের খুব ভাল উত্তর is অনেক কারণ, তবে আপনি কিছু ইনস্টল করার ক্ষমতা ছাড়াই ম্যাক ওএস মেশিনগুলিকে লক্ষ্য করে নিচ্ছেন। pwd -Pবেশ সহজ তবে এটি বারবার উত্তরগুলি সহ আরও অনেক উত্তরের মধ্যে অদৃশ্য হয়ে যায়, তাই ডাউনভোট।
জেসন এস

3

আপডেট শুরু করুন

এটি এমন একটি ঘন ঘন সমস্যা যা আমরা রিয়েলপ্যাথ-লাইব নামে বিনামূল্যে ব্যবহারের জন্য বাশ 4 লাইব্রেরি (এমআইটি লাইসেন্স) রেখেছি । এটি ডিফল্টরূপে রিডলিংক -f অনুকরণ করার জন্য ডিজাইন করা হয়েছে এবং এটি পরীক্ষা করাতে দুটি পরীক্ষা স্যুট অন্তর্ভুক্ত করে (1) যা কোনও প্রদত্ত ইউনিক্স সিস্টেমের জন্য কাজ করে এবং (2) রিডলিংক -f ইনস্টল করা থাকলে (তবে এটি প্রয়োজনীয় নয়)। তদ্ব্যতীত, এটি গভীর, ভাঙা প্রতীক এবং বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সগুলি অনুসন্ধান, সনাক্তকরণ এবং আনইন্ডাইন্ড করতে ব্যবহার করা যেতে পারে, তাই এটি গভীরভাবে নেস্টেড শারীরিক বা প্রতীকী ডিরেক্টরি এবং ফাইল সমস্যাগুলি নির্ণয়ের জন্য একটি দরকারী সরঞ্জাম হতে পারে। এটা তোলে পাওয়া যাবে github.com বা bitbucket.org

শেষ আপডেট

আরেকটি খুব কমপ্যাক্ট এবং দক্ষ সমাধান যা বাশ ব্যতীত কোনও কিছুর উপর নির্ভর করে না:

function get_realpath() {

    [[ ! -f "$1" ]] && return 1 # failure : file does not exist.
    [[ -n "$no_symlinks" ]] && local pwdp='pwd -P' || local pwdp='pwd' # do symlinks.
    echo "$( cd "$( echo "${1%/*}" )" 2>/dev/null; $pwdp )"/"${1##*/}" # echo result.
    return 0 # success

}

এটিতে একটি পরিবেশ সেটিং অন্তর্ভুক্ত রয়েছে no_symlinksযা শারীরিক সিস্টেমে সিমলিংকগুলি সমাধান করার ক্ষমতা সরবরাহ করে। যতক্ষণ কোনও কিছুর no_symlinksউপর সেট করা থাকে, যেমনno_symlinks='on' কোনও কিছুর ততক্ষণ সিমলিংকগুলি শারীরিক সিস্টেমে সমাধান করা হবে। অন্যথায় সেগুলি প্রয়োগ করা হবে (ডিফল্ট সেটিংস)।

এটি ব্যাশ সরবরাহকারী কোনও সিস্টেমে কাজ করা উচিত এবং পরীক্ষার উদ্দেশ্যে বাশ সামঞ্জস্যপূর্ণ প্রস্থান কোডটি ফিরিয়ে দেবে।


3

ইতিমধ্যে প্রচুর উত্তর রয়েছে, কিন্তু কেউই আমার পক্ষে কাজ করেনি ... সুতরাং আমি এখন এটি ব্যবহার করছি।

readlink_f() {
  local target="$1"
  [ -f "$target" ] || return 1 #no nofile

  while [ -L "$target" ]; do
    target="$(readlink "$target")" 
  done
  echo "$(cd "$(dirname "$target")"; pwd -P)/$target"
}

1
এটি যদি $targetপথ হয় তবে এটি কাজ করে না , এটি কেবল ফাইল হলেই এটি কাজ করে।
ম্যাক্সহোস্ট

3

একটি অলস উপায় যা আমার পক্ষে কাজ করে,

$ brew install coreutils
$ ln -s /usr/local/bin/greadlink /usr/local/bin/readlink
$ which readlink
/usr/local/bin/readlink
/usr/bin/readlink

1

আমি মনে করি না এর চেয়ে বেশি দেরি করি। আমি বিশেষত এটি বিকাশ করতে অনুপ্রাণিত হয়েছিল কারণ আমার ফেডোরা স্ক্রিপ্টগুলি ম্যাকের সাথে কাজ করছে না। সমস্যা নির্ভরতা এবং বাশ। ম্যাকগুলির সেগুলি নেই, বা যদি তা হয় তবে তারা প্রায়শই অন্য কোথাও (অন্য কোনও পথ) থাকে। ক্রস-প্ল্যাটফর্ম বাশ স্ক্রিপ্টে নির্ভরতা পথের হেরফেরটি সর্বোপরি মাথা ব্যথা এবং সবচেয়ে খারাপ দিক থেকে সুরক্ষা ঝুঁকি - তাই যদি সম্ভব হয় তবে তাদের ব্যবহার এড়ানো ভাল।

নীচে get_relpath () ফাংশনটি সহজ, বাশকেন্দ্রিক এবং কোনও নির্ভরতার প্রয়োজন নেই। আমি কেবল ব্যাশ বিল্টিন ইকো এবং সিডি ব্যবহার করি । এটিও মোটামুটি সুরক্ষিত, কারণ প্রতিটি পথে প্রতিটি পর্যায়ে পরীক্ষা করা হয় এবং এটি ত্রুটির শর্ত ফেরায়।

আপনি symlinks অনুসরণ করতে না চান তাহলে, তারপর করা সেট -P স্ক্রিপ্ট সামনে, কিন্তু অন্যথায় সিডি ডিফল্টরূপে symlinks সমাধান করা উচিত নয়। এটি সম্পূর্ণরূপে ফাইল আর্গুমেন্টগুলির সাথে পরীক্ষা করা হয়েছে আপেক্ষিক | syMLink | স্থানীয়} এবং এটি ফাইলে পরম পথ ফেরায়। এখনও পর্যন্ত এটি নিয়ে আমাদের কোনও সমস্যা হয়নি।

function get_realpath() {

if [[ -f "$1" ]]
then
    # file *must* exist
    if cd "$(echo "${1%/*}")" &>/dev/null
    then
        # file *may* not be local
        # exception is ./file.ext
        # try 'cd .; cd -;' *works!*
        local tmppwd="$PWD"
        cd - &>/dev/null
    else
        # file *must* be local
        local tmppwd="$PWD"
    fi
else
    # file *cannot* exist
    return 1 # failure
fi

# reassemble realpath
echo "$tmppwd"/"${1##*/}"
return 0 # success

}

আপনি এটি অন্যান্য ফাংশন get_dirname, get_filename, get_stename এবং বৈধতা_পথের সাথে একত্রিত করতে পারেন। এগুলি আমাদের গিটহাবের সংগ্রহস্থলটিতে রিয়েলপথ-লিব হিসাবে পাওয়া যাবে (সম্পূর্ণ প্রকাশ - এটি আমাদের পণ্য তবে আমরা এটি কোনও বিধিনিষেধ ছাড়াই সম্প্রদায়কে বিনামূল্যে অফার করি)। এটি একটি নির্দেশমূলক সরঞ্জাম হিসাবেও কাজ করতে পারে - এটি ভাল নথিভুক্ত।

আমরা তথাকথিত 'আধুনিক বাশ' অনুশীলনগুলি প্রয়োগ করার জন্য যথাসাধ্য চেষ্টা করেছি, তবে বাশ একটি বড় বিষয় এবং আমি নিশ্চিত যে এখানে সর্বদা উন্নতির অবকাশ থাকবে। এর জন্য ব্যাশ 4+ লাগবে তবে তারা যদি এখনও থাকে তবে পুরানো সংস্করণগুলির সাথে কাজ করা যায়।


1

যেহেতু আমার কাজটি নন-বিএসডি লিনাক্স এবং ম্যাকোসযুক্ত ব্যক্তিরা ব্যবহার করেন, তাই আমি এই বিলিয়াগুলি আমাদের বিল্ড স্ক্রিপ্টগুলিতে ব্যবহার করার পক্ষে বেছে নিয়েছি ( sedএতে একই সমস্যা রয়েছে বলে অন্তর্ভুক্ত):

##
# If you're running macOS, use homebrew to install greadlink/gsed first:
#   brew install coreutils
#
# Example use:
#   # Gets the directory of the currently running script
#   dotfilesDir=$(dirname "$(globalReadlink -fm "$0")")
#   alias al='pico ${dotfilesDir}/aliases.local'
##

function globalReadlink () {
  # Use greadlink if on macOS; otherwise use normal readlink
  if [[ $OSTYPE == darwin* ]]; then
    greadlink "$@"
  else
    readlink "$@"
  fi
}

function globalSed () {
  # Use gsed if on macOS; otherwise use normal sed
  if [[ $OSTYPE == darwin* ]]; then
    gsed "$@"
  else
    sed "$@"
  fi
}

Automatically চ্ছিক চেক আপনি স্বয়ংক্রিয়ভাবে হোমব্রিউ + কোর্টিলস নির্ভরতা ইনস্টল করতে যোগ করতে পারেন :

if [[ "$OSTYPE" == "darwin"* ]]; then
  # Install brew if needed
  if [ -z "$(which brew)" ]; then 
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"; 
  fi
  # Check for coreutils
  if [ -z "$(brew ls coreutils)" ]; then
    brew install coreutils
  fi
fi

আমি মনে করি সত্যিকারের "গ্লোবাল" হওয়ার জন্য এটি অন্যকে যাচাই করা দরকার ... তবে সম্ভবত এটি 80/20 চিহ্নের কাছাকাছি চলে আসে।


1

ব্যাখ্যা

কোর্টিলস হ'ল একটি brewপ্যাকেজ যা জিএনইউ / লিনাক্স কোর ইউটিলিটিগুলি ইনস্টল করে যা ম্যাক ওএসএক্স বাস্তবায়নের সাথে সামঞ্জস্য করে যাতে আপনি সেগুলি ব্যবহার করতে পারেন

আপনি আপনার ম্যাক ওক্স সিস্টেমে এমন প্রোগ্রাম বা ইউটিলিটিগুলি খুঁজে পেতে পারেন যা লিনাক্স কোরিউটিলস ("কোর ইউটিলিটিস") এর মতো বলে মনে হয় তবুও তারা কিছু উপায়ে (যেমন আলাদা পতাকা লাগানো) আলাদা হয়।

কারণ এই সরঞ্জামগুলির ম্যাক ওএসএক্স বাস্তবায়ন আলাদা। মূল জিএনইউ / লিনাক্সের মতো আচরণ পেতে আপনি প্যাকেজ পরিচালনা সিস্টেমের coreutilsমাধ্যমে প্যাকেজটি ইনস্টল করতে পারেন brew

এটি দ্বারা উপস্থাপিত, সংশ্লিষ্ট মূল ইউটিলিটিগুলি ইনস্টল করবে g। উদাহরণস্বরূপ readlink, আপনি একটি সম্পর্কিত greadlinkপ্রোগ্রাম পাবেন।

readlinkজিএনইউ readlink( greadlink) প্রয়োগের মতো পারফর্ম করার জন্য , আপনি কোর্টিলগুলি ইনস্টল করার পরে আপনি একটি সাধারণ ওরফে তৈরি করতে পারেন।

বাস্তবায়ন

  1. মেশান ইনস্টল করুন

Https://brew.sh/ এ নির্দেশাবলী অনুসরণ করুন

  1. কোর্টিলস প্যাকেজ ইনস্টল করুন

brew install coreutils

  1. একটি উপনাম তৈরি করুন

আপনি আপনার উপন্যাসটি ~ / .bashrc, ~ / .bash_profile, বা আপনি যেখানেই আপনার ব্যাশের উপাধি রাখতে অভ্যস্ত হন সেখানে রাখতে পারেন। আমি ব্যক্তিগতভাবে আমার ~ / .bashrc এ রাখি

alias readlink=greadlink

আপনি অন্যান্য কোরিউটিলে যেমন জিএমভি, জিডিইউ, জিডিএফ ইত্যাদির জন্য অনুরূপ উপকরণ তৈরি করতে পারেন। তবে সাবধান থাকুন যে ম্যাক মেশিনে জিএনইউ আচরণটি দেশীয় কোর্টিলগুলি নিয়ে কাজ করার জন্য ব্যবহৃত অন্যদের জন্য বিভ্রান্ত হতে পারে, বা আপনার ম্যাক সিস্টেমে অপ্রত্যাশিতভাবে আচরণ করতে পারে।


0

আমি ওএস এক্স এর জন্য একটি রিয়েলপথ ইউটিলিটি লিখেছি যা একই ফলাফল প্রদান করতে পারে readlink -f


এখানে একটি উদাহরণ:

(jalcazar@mac tmp)$ ls -l a
lrwxrwxrwx 1 jalcazar jalcazar 11  8 25 19:29 a -> /etc/passwd

(jalcazar@mac tmp)$ realpath a
/etc/passwd


আপনি MacPorts ব্যবহার করে থাকেন, আপনি নিম্নলিখিত কমান্ড ব্যবহার করে ইনস্টল করতে পারেন: sudo port selfupdate && sudo port install realpath


0

সত্যিকার অর্থে প্ল্যাটফর্ম-নির্ভরশীলও এই আর-অনলাইনার হবে

readlink(){ RScript -e "cat(normalizePath(commandArgs(T)[1]))" "$1";}

আসলে নকল করতে readlink -f <path>, $ 1 এর পরিবর্তে $ 2 ব্যবহার করা প্রয়োজন।


আর ব্যতীত ডিফল্টরূপে কোনও সিস্টেমে খুব কমই। এখনও ম্যাক এ নেই (10.15 হিসাবে) যা এই প্রশ্নটি সম্পর্কে।
কোডনিফার

0

পসিক্স readlink -fশেল স্ক্রিপ্টগুলির জন্য POSIX মেনে চলার প্রয়োগ

https://github.com/ko1nksm/readlinkf

এটি পসিক্স কমপ্লায়েন্ট (কোনও বাশিজম নয়)। এটি ব্যবহার করে তন্ন তন্ন readlinkনা realpath। আমি GNU এর সাথে তুলনা করে যাচাই করেছি readlink -f( পরীক্ষার ফলাফল দেখুন )। এটিতে ত্রুটি পরিচালনা ও ভাল পারফরম্যান্স রয়েছে। আপনি নিরাপদে থেকে প্রতিস্থাপন করতে পারেন readlink -f। লাইসেন্সটি সিসি0, সুতরাং আপনি এটি কোনও প্রকল্পের জন্য ব্যবহার করতে পারেন।

# POSIX compliant version
readlinkf_posix() {
  [ "${1:-}" ] || return 1
  target=$1 max_symlinks=10 CDPATH=''

  [ -e "${target%/}" ] || target=${1%"${1##*[!/]}"} # trim trailing slashes
  [ -d "${target:-/}" ] && target="$target/"

  cd -P . 2>/dev/null || return 1
  while [ "$max_symlinks" -gt 0 ] && max_symlinks=$((max_symlinks - 1)); do
    if [ ! "$target" = "${target%/*}" ]; then
      cd -P "${target%/*}/" 2>/dev/null || break
      target=${target##*/}
    fi

    if [ ! -L "$target" ]; then
      target="${PWD%/}${target:+/}$target"
      printf '%s\n' "${target:-/}"
      return 0
    fi

    # `ls -dl` format: "%s %u %s %s %u %s %s -> %s\n",
    #   <file mode>, <number of links>, <owner name>, <group name>,
    #   <size>, <date and time>, <pathname of link>, <contents of link>
    # https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html
    link=$(ls -dl "$target" 2>/dev/null) || break
    target=${link#*" $target -> "}
  done
  return 1
}

সর্বশেষ কোড উল্লেখ করুন। এটি কিছু স্থির হতে পারে।


-2

পার্লের একটি রিডলিংক ফাংশন রয়েছে (যেমন আমি পার্লে প্রতীকী লিঙ্কগুলি কীভাবে অনুলিপি করব? )। এটি ওএস এক্স সহ বেশিরভাগ প্ল্যাটফর্ম জুড়ে কাজ করে:

perl -e "print readlink '/path/to/link'"

উদাহরণ স্বরূপ:

$ mkdir -p a/b/c
$ ln -s a/b/c x
$ perl -e "print readlink 'x'"
a/b/c

5
এটি বিকল্প readlinkছাড়াই একই কাজ করে -f- কোনও পুনরাবৃত্তি, কোনও নিখুঁত পথ - যাতে আপনি readlinkসরাসরি ব্যবহার করতে পারেন ।
mklement0

-2

@ কিথ স্মিথের উত্তর একটি অসীম লুপ দেয়।

এখানে আমার উত্তরটি দেওয়া হয়েছে, যা আমি কেবল সানস-এ ব্যবহার করি (সানোস এত বেশি পসিক্স এবং জিএনইউ কমান্ড মিস করে)।

এটি একটি স্ক্রিপ্ট ফাইল যা আপনার আপনার $ PATH ডিরেক্টরিগুলির একটিতে রাখতে হবে:

#!/bin/sh
! (($#)) && echo -e "ERROR: readlink <link to analyze>" 1>&2 && exit 99

link="$1"
while [ -L "$link" ]; do
  lastLink="$link"
  link=$(/bin/ls -ldq "$link")
  link="${link##* -> }"
  link=$(realpath "$link")
  [ "$link" == "$lastlink" ] && echo -e "ERROR: link loop detected on $link" 1>&2 && break
done

echo "$link"


-5

পঠন-সংযোগের পথগুলি আমার সিস্টেম এবং আপনার মধ্যে পৃথক। সম্পূর্ণ পথ নির্দিষ্ট করার চেষ্টা করুন:

/sw/sbin/readlink -f


1
এবং কি - ঠিক - / sw / sbin এবং / usr / বিন মধ্যে পার্থক্য? এবং কেন দুটি বাইনারি আলাদা হয়?
ট্রয়সল্কন

4
আহা .. সুতরাং fink এর জন্য একটি প্রতিস্থাপন রয়েছে readlinkgnu সামঞ্জস্যপূর্ণ। এটি জেনে রাখা ভাল, তবে এটি আমার সমস্যার সমাধান করতে পারে না, যেহেতু অন্যান্য স্ক্রিপ্টের মেশিনে চালানোর জন্য আমার স্ক্রিপ্টটি দরকার এবং এর জন্য আমি তাদের ফিঙ্ক ইনস্টল করার প্রয়োজনও করতে পারি না।
ট্রয়েস্কেন 11

আপনি মূল প্রশ্নের উত্তর দিচ্ছেন না। আপনার উত্তর পুনরায় লিখুন।
জাইমে হাবলুটজেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.