প্রতীকী লিঙ্ক ছাড়াই আপেক্ষিক পাথকে নিখুঁত পথে রূপান্তর করা


63

প্রতীকী লিঙ্কগুলি থাকতে পারে এমন কোনও আপেক্ষিক পথ থেকে নিখুঁত (এবং ক্যানোনিকালাইজড) পাথ পেতে কোনও ইউনিক্স আদেশ আছে?

উত্তর:


79

আপনি বিকল্পটি readlinkসহ ইউটিলিটিটি ব্যবহার করতে পারেন -f:

-f, --canonicalize

      canonicalize  by  following  every symlink in every component of
      the given name recursively; all  but  the  last  component  must
      exist

কিছু বিতরণ, যেমন জিএনইউ কোর্টিলস এবং ফ্রিবিএসডি ব্যবহার করে , এমন একটি realpath(1)ইউটিলিটিও আসে যা মূলত কেবল কল করে realpath(3)এবং একই জিনিসটি করে।


16
-fসুইচ Mac OS X এর (অন্তত 10.8.5 হিসাবে) উপর কোন অস্তিত্ব নেই। -fসুইচ ব্যতীত এটি কেবল একটি ত্রুটি কোড দেয়।
আইকনোক্লাস্ট

3
কিছু সিস্টেমের সাথে তন্ন তন্ন আসা readlinkকিংবা realpathসোলারিস এবং HP-ইউএক্স বিশেষ করে -।
সিলডোরথ

ম্যাক ইস্যুটির জন্য: brew install coreutils আপেল.স্ট্যাকেক্সেঞ্জ / ডটকম / এ / 69332/23040 , এবং আপনি যদি এমন পদক্ষেপটি করতে চান না যা সদ্য ইনস্টল করা জিএনইউ সমতুল্যে সমস্ত মানক ম্যাক সিএলআই সরঞ্জাম পুনঃনির্দেশ করে, কেবল কল করুন greadlink
এড্রিয়ান

18

পোর্টেবলভাবে, PWDভেরিয়েবলটি শেল দ্বারা বর্তমান ডিরেক্টরিতে একটি পরম স্থানে সেট করা হয়। সেই পথের যে কোনও উপাদান প্রতীকী লিঙ্ক হতে পারে।

case $f in
  /*) absolute=$f;;
  *) absolute=$PWD/$f;;
esac

আপনি যদি মুছে ফেলা .এবং ..পাশাপাশি করতে চান তবে ফাইল ধারণকারী ডিরেক্টরিতে পরিবর্তন করুন এবং $PWDসেখানে পান:

if [ -d "$f" ]; then f=$f/.; fi
absolute=$(cd "$(dirname -- "$f")"; printf %s. "$PWD")
absolute=${absolute%?}
absolute=$absolute/${f##*/}

প্রতীকী লিঙ্কগুলি অনুসরণ করার মতো কোনও পোর্টেবল উপায় নেই। আপনার যদি কোনও ডিরেক্টরিতে যাওয়ার পথ থাকে, তবে বেশিরভাগ ইউনিটেই $(cd -- "$dir" && pwd -P 2>/dev/null || pwd)এমন একটি পথ সরবরাহ করে যা প্রতীকী লিঙ্কগুলি ব্যবহার করে না, কারণ প্রতীকী লিঙ্কগুলি ট্র্যাক করা শেলগুলি pwd -P"শারীরিক" জন্য "পি" প্রয়োগ করে ।

কিছু ইউনিক একটি ফাইলের "শারীরিক" পাথ মুদ্রণের জন্য একটি ইউটিলিটি সরবরাহ করে।

  • যুক্তিসঙ্গতভাবে সাম্প্রতিকতম লিনাক্স সিস্টেমগুলিতে (জিএনইউ কোর্টিলস বা ব্যাসিবক্স সহ) readlink -fফ্রিবিএসডি -8.3, নেটবিএসডি -৪.০, এবং ওপেনবিএসডি যেমন রয়েছে ২.২।
  • ফ্রিবিএসডি -৪.৩-তে রয়েছে realpath(এটি কিছু লিনাক্স সিস্টেমে উপস্থিত রয়েছে এবং এটি ব্যাসিবক্সে রয়েছে )।
  • পার্ল উপলভ্য থাকলে আপনি Cwdমডিউলটি ব্যবহার করতে পারেন ।

    perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/file

আপনি কেন কোনও কিছুতে পাইপ করেন pwd( $(cd -- "$dir" && pwd -P 2>/dev/null | pwd))? এটা স্টিডিন সম্পর্কে যত্ন বলে মনে হচ্ছে না।
ম্যাটিউজ পিয়োত্রস্কি

1
@ ম্যাটিউজপিয়োট্রোস্কি টাইপো, আমি লিখতে চেয়েছিলাম||
গিলস

5

Is pwdআপনার প্রয়োজনের জন্য মাপসই করা হবে? এটি বর্তমান ডিরেক্টরিটির পরম পথ দেয়। অথবা আপনি যা চান তা হ'ল রিয়েলপথ ()


3

alisterএবং rss67মধ্যে এই নিবন্ধটি , সবচেয়ে স্থিতিশীল সামঞ্জস্যপূর্ণ এবং সহজ পদ্ধিতি হল উপায় পরিচয় দিন। আমি এর আগে এর চেয়ে ভাল আর কখনও দেখিনি।

RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`

আপনি যদি মূল জায়গায় ফিরে যেতে চান,

ORGPATH=`pwd`
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd $ORGPATH

অথবা

RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd -

আমি আশা করি এই সাহায্য করে। এটি ছিল আমার পক্ষে সবচেয়ে বড় সমাধান।


12
আসলে এটি এত ভাল উপায় নয়। ডিরেক্টরি থেকে বেরিয়ে আসা এবং ফিরে আসা নির্ভরযোগ্য নয়: আপনার কাছে ফিরে আসার অনুমতি নাও থাকতে পারে বা এরই মধ্যে ডিরেক্টরিটির নতুন নামকরণ করা যেতে পারে। পরিবর্তে, subshell মধ্যে ডিরেক্টরি পরিবর্তন করুন: ABSPATH=$(cd -- "$RELPATH" && pwd)। প্রতিস্থাপনের আশেপাশের দ্বৈত উক্তিগুলি নোট করুন (যাতে পথে সাদা অংশ এবং গ্লোববিং অক্ষর রয়েছে কিনা তা ভঙ্গ করবেন না) এবং --(পথটি যদি শুরু হয় তবে -)। এছাড়াও এটি কেবল ডিরেক্টরিগুলির জন্যই কাজ করে, এবং অনুরোধ অনুসারে প্রতীকী লিঙ্কগুলিকে আকাঙ্ক্ষিত করে না। আরও তথ্যের জন্য আমার উত্তর দেখুন।
গিলস

"> আপনার কাছে ফিরে আসার অনুমতি নাও থাকতে পারে" আপনার অর্থ সিডির একটা দির কিন্তু সিডি ফিরে আসতে পারবে না? আপনি দয়া করে কিছু উদাহরণ পরিস্থিতিতে সরবরাহ করতে পারেন।
টেলসপিন_কিট

0

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

#!/bin/sh
if [ $# -eq 0 ] || [ $# -gt 2 ]; then
  printf 'Usage: respath path [working-directory]\n' >&2
  exit 1
fi
cantGoUp=

path=$1
if [ $# -gt 1 ]; then
  cd "$2"
fi
cwd=`pwd -P` #Use -P option to account for directories that are actually symlinks

#Handle non-relative paths, which don't need resolution
if echo "$path" | grep '^/' > /dev/null ; then
  printf '%s\n' "$path"
  exit 0
fi

#Resolve for each occurrence of ".." at the beginning of the given path.
#For performance, don't worry about ".." in the middle of the path.
while true
do
  case "$path" in
    ..*)
      if [ "$cwd" = '/' ]; then
        printf 'Invalid relative path\n' >&2
        exit 1
      fi
      if [ "$path" = '..' ]; then
        path=
      else
        path=`echo "$path" | sed 's;^\.\./;;'`
      fi
      cwd=`dirname $cwd`
      ;;
    *)
      break
      ;;
  esac
done

cwd=`echo "$cwd" | sed 's;/$;;'`
if [ -z "$path" ]; then
  if [ -z "$cwd" ]; then
    cwd='/'
  fi
  printf '%s\n' "$cwd"
else
  printf '%s/%s\n' "$cwd" "$path"
fi

এই সমাধানটি বহনযোগ্যতার জন্য বোর্ন শেলের জন্য লেখা written আমার কাছে এটি "রিস্যাথ.শ" নামে একটি স্ক্রিপ্টে আছে।

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

respath.sh '/path/to/file'

বা এই মত

respath.sh '/relative/path/here' '/path/to/resolve/relative/to'

স্ক্রিপ্টটি প্রথম আর্গুমেন্টের মধ্যে দ্বিতীয় আর্গুমেন্ট থেকে শুরু করে পয়েন্ট হিসাবে পাথটি ব্যবহার করে পাথটি সমাধান করে। যদি কেবল প্রথম যুক্তি সরবরাহ করা হয় তবে স্ক্রিপ্টটি আপনার বর্তমান কার্যনির্বাহী ডিরেক্টরি সম্পর্কিত পথটিকে সমাধান করে।


মনে রাখবেন যে আপনি সম্ভবত সোলারিস 10 এবং এর আগে আজকাল একটি বোর্ন শেল পাবেন। যে বোর্ন শেলটি সর্বাধিক বোর্ন শেল বাস্তবায়ন যেমন এসভিআর 2 (1984) তৈরি করেছে pwdএবং সমর্থন করে না -P(বোর্ন শেল সেই লজিক্যাল $ পিডাব্লুডি হ্যান্ডলিং পসিক্স শেলগুলির মতো প্রয়োগ করে না)।
স্টাফেন চেজেলাস

যদি আপনি বোর্ন সামঞ্জস্যতা বাদ দেন তবে আপনি পসিক্স {{ভার ## প্যাটার্ন} সিনট্যাক্সটি ব্যবহার করতে পারেন এবং কিছু প্রতিপন্ন হওয়া ইকো | সেড এড়াতে পারেন some
স্টাফেন চেজেলাস

আপনার সিডির প্রস্থান স্থিতি পরীক্ষা করতে ভুলে গেছেন (এবং পিডাব্লুডি)। cd -P --প্রথম যুক্তিতে কিছু থাকতে পারে আপনার সম্ভবত ব্যবহার করা উচিত ..
স্টাফেন চেজেলাস

আপনার caseচেক এর ..|../*)পরিবর্তে হওয়া উচিত ..*
স্টাফেন চেজেলাস

এর মধ্যে উদ্ধৃতিগুলির নিখোঁজের একটি মামলা রয়েছেdirname $cwd
স্টাফেন চেজেলাস

0

ক্ষেত্রে, অতিরিক্তভাবে, আপনার $1(সাধারণত ${PWD}) জন্য কিছু পূর্বনির্ধারিত পথ রয়েছে তবে নিম্নলিখিতগুলি কাজ করবে:

CWD="${1:-${PredefinedAbsolutePath}}"
if [ "${CWD}" != "${PredefinedAbsolutePath}}" ]; then
    case $1 in
        /*) echo "CWD=${CWD}"; ;;
        *) CWD=$(realpath $1); echo "CWD=${CWD}"; ;;
    esac
fi

0

অন্য সকলের জবাবের প্রতি শ্রদ্ধা জানিয়ে আমি নীচের ফাংশনটি লিনাক্স / ম্যাক ওএসএক্সের মধ্যে অন্যত্রের চেয়ে খুব সহজে এবং পোর্টেবল হিসাবে খুঁজে পেয়েছি বলে আমি খুঁজে পেয়েছি everywhere কাউকে সাহায্য করতে পারে।

#!/usr/bin/bash
get_absolute_path(){
    file_path=`pwd $1`
    echo "$file_path/$1"
}
#to assign to a variable
absolute_path=$(get_absolute_path "file.txt")
echo $absolute_path

-1

ভেরিয়েবল একটি স্টোরের পাথের নাম ধরে রাখুন (a = "যাই হোক না কেন")

1. সম্ভাব্য স্থান-সহ পাথের জন্য:

c=$(grep -o " " <<< $a | wc -l); if (( $c > "0" )); then a=$(sed 's/ /\\ /g' <<< $a); fi

২. প্রকৃত প্রশ্নের জন্য, অর্থাৎ নিরঙ্কুশ পথে রূপান্তর করার জন্য: রিডলিঙ্কটি সিমলিংক সামগ্রীগুলি পুনরুদ্ধার করতে পারে, যা নিম্নলিখিত হিসাবে নিযুক্ত করা যায়। (নোট readlink -fনিখুঁত হত কিন্তু অন্তত ম্যাক OS X ব্যাশ, যা পাওয়া যায় না -f ঘোরা ফরম্যাটের ।)

if [[ $(readlink $a) == "" ]]; then a=$(cd $a; pwd); else a=$(cd $(readlink $a); pwd); fi

3. শুধু শিখেছি pwd -Pমধ্যে man pwd: -P "হয় শারীরিক সাম্প্রতিক কাজ করা প্রদর্শন (সমস্ত সিম্বলিক লিংক সমাধান) " এবং অত: পর

if (( $(grep -o " " <<< $a | wc -l) > "0" )); then a=$(sed 's/ /\\ /g' <<< $a); fi; a=$(cd $a; pwd -P)

কাজ করবে।

উপসংহার: আপনার উভয় প্রয়োজনীয়তা মেটাতে 1 এর সাথে 2 টি একত্রিত করুন , যদিও স্থান সংবলিত পাথের নামগুলি ইতিমধ্যে আরও সংক্ষিপ্ত 3 তে যত্ন নেওয়া হয়েছে ।


আপনি গু (র) প্রবন্ধ ভুল উদাহরণস্বরূপ, যদি আপনার পথে উপরের অভ্যাসের বেশিরভাগ জায়গাই অন্তর্ভুক্ত থাকে।
আনথন

বা কখনও কখনও একটি গ্লোব চর। এবং এটি অনুরোধগুলি সমাধান করে না, যেমনটি অনুরোধ করা হয়েছিল।
dave_thompson_085

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