প্রদত্ত আপেক্ষিক উপায় কীভাবে পুনরুদ্ধার করবেন


159

আপেক্ষিক পথ প্রদত্ত পরম পথটি পুনরুদ্ধার করার জন্য কোন আদেশ আছে?

উদাহরণস্বরূপ আমি want লাইনটি dir প্রতিটি ফাইলের পরম পথ থাকতে চাই to ./etc/

find ./ -type f | while read line; do
   echo $line
done


1
অনুলিপি সদৃশ নয়, একই
mpapis


উত্তর:


66

ব্যবহার করুন:

find "$(pwd)"/ -type f

সমস্ত ফাইল পেতে বা

echo "$(pwd)/$line"

সম্পূর্ণ পাথ প্রদর্শন করতে (যদি আপেক্ষিক পথটি গুরুত্বপূর্ণ)


2
আমি যদি অনুসন্ধানের ক্ষেত্রে কোনও আপেক্ষিক পথ নির্দিষ্ট করি ??
নবুমে

17
তারপরে আপনার প্রশ্নের মন্তব্যে লিঙ্কগুলি দেখুন, সর্বোত্তম উপায় সম্ভবত 'রিডলিংক-ফ $ লাইন'
এমপিপিস

3
কেন $(pwd)জায়গায় ব্যবহার $PWD? (হ্যাঁ, আমি জানি pwdএকটি বিল্টিন)
অ্যাডাম কাটজ

178

ব্যবহার করে দেখুন realpath

~ $ sudo apt-get install realpath  # may already be installed
~ $ realpath .bashrc
/home/username/.bashrc

সিমলিঙ্কগুলি প্রসারিত এড়াতে, ব্যবহার করুন realpath -s

উত্তরটি " ফাইলের জন্য পরম পাথ মুদ্রণের জন্য বাশ / ফিশ কমান্ড " থেকে আসে ।


11
realpathম্যাকটিতে উপলব্ধ বলে মনে হচ্ছে না (ওএস এক্স 10.11 "এল ক্যাপিটান")। :-(
ল্যারিক্স ডিডিডুয়া

realpathমনে হয় না যে এটি
সেন্টোস

6
অসক্সে, brew install coreutilsআনতে হবেrealpath
কেভিন চেন

আমার উবুন্টু 18.04 realpathএ ইতিমধ্যে উপস্থিত রয়েছে। আমার এটি আলাদাভাবে ইনস্টল করতে হবে না।
একিউম্যানাস

আশ্চর্যজনকভাবে, realpathউইন্ডোজের জন্য গিটে পাওয়া যায় (আমার পক্ষে, কমপক্ষে)।
অ্যান্ড্রু কিটন

104

আপনার যদি কোরিউটিলস প্যাকেজটি ইনস্টল করা থাকে তবে আপনি সাধারণত নিখুঁতটি readlink -f relative_file_nameপুনরুদ্ধার করতে ব্যবহার করতে পারেন (সমস্ত প্রতিলিপি সমাধানের সাথে)


3
এর জন্য ব্যবহারকারীর জিজ্ঞাসা থেকে কিছুটা আলাদা, এটি পথের যে কোনও জায়গায় পুনরাবৃত্ত প্রতীকগুলি অনুসরণ এবং সমাধান করবে। আপনি কিছু ক্ষেত্রে এটি নাও চাইতে পারেন।

1
@ ব্র্যাডপিবাডি যদি আপনি হোমব্রু থেকে কোর্টিলগুলি ইনস্টল করেন তবে এটি ম্যাকের কাজ করে brew install coreutils। তবে এক্সিকিউটেবলটি এ.জি. দ্বারা চালিত হয়:greadlink -f relative_file_name
মিগুয়েল ইসলা

2
লক্ষ্য করুন যে পঠন লিঙ্কের ম্যানুয়াল পৃষ্ঠাতে (1) এর বর্ণনার প্রথম বাক্য রয়েছে: "নোট রিয়েলপথ (1) ক্যানোনিকালাইজেশন কার্যকারিতার জন্য ব্যবহার করার জন্য পছন্দসই কমান্ড" "
জোছ

1
ফাইল / ডিরেক্টরি উপস্থিত রয়েছে কিনা তা পরীক্ষা করতে আপনি -f এর পরিবর্তে -e ব্যবহার করতে পারেন
আইসম্যান

69
#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"

UPD কিছু ব্যাখ্যা

  1. এই স্ক্রিপ্টটি যুক্তি হিসাবে আপেক্ষিক পথ পায় get "$1"
  2. তারপরে আমরা dirname পাই সেই পথটির অংশ (আপনি এই স্ক্রিপ্টে দির বা ফাইল পাস করতে পারেন):dirname "$1"
  3. তারপরে আমরা cd "$(dirname "$1")এই আপেক্ষিক dir এর মধ্যে প্রবেশ করি এবং pwdশেল কমান্ড চালিয়ে এর জন্য পরম পথ পাবো
  4. এর পরে আমরা বেসনেমকে পরম পথে যুক্ত করি:$(basename "$1")
  5. চূড়ান্ত পদক্ষেপ হিসাবে আমরা echoএটা

8
এই উত্তরটি সেরা বাশ প্রতিমা ব্যবহার করে
রোন্ডো

2
রিডলিঙ্কটি লিনাক্সের সহজ সমাধান, তবে এই সমাধানটি
ওএসএক্সেও

1
এই স্ক্রিপ্টটি কি realpathবা করার সমান নয় readlink -f। উদাহরণস্বরূপ, এটি এমন পাথগুলিতে কাজ করে না যেখানে শেষ উপাদানটি একটি সিমলিংক।
জোছ

2
@ জোছ: প্রশ্নটি সিমলিংক সমাধানের নয়। তবে আপনি যদি এটি করতে চান তবে আপনি আদেশ -Pদেওয়ার বিকল্পটি প্রদান করতে পারেন pwd:echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"
ইউজেন কনকভ

4
আমি উত্তরটি পছন্দ করি তবে এটি কেবলমাত্র কাজ করে, যদি ব্যবহারকারীকে ডিরেক্টরিতে সিডির অনুমতি দেওয়া হয়। এটি সর্বদা সম্ভব নাও হতে পারে।
ম্যাথিয়াস বি

34

এর মূল্য কী, তার জন্য আমি যে উত্তরটি নেওয়া হয়েছিল তার পক্ষে ভোট দিয়েছি, তবে একটি সমাধান ভাগ করে নিতে চাই। ক্ষতিটি হ'ল এটি কেবল লিনাক্স - স্ট্যাক ওভারফ্লোতে আসার আগে আমি প্রায় 5 মিনিট ওএসএক্সের সমতুল্য খুঁজতে চেষ্টা করেছিলাম। আমি নিশ্চিত যে এটি বাইরে আছে।

লিনাক্স উপর আপনি ব্যবহার করতে পারেন readlink -eটমটম dirname

$(dirname $(readlink -e ../../../../etc/passwd))

উৎপাদনের

/etc/

এবং তারপরে আপনি কেবল ফাইলের নাম পেতে dirname, basenameআপনার বোন ব্যবহার করেন

$(basename ../../../../../passwd)

উৎপাদনের

passwd

সব একসাথে রাখুন ..

F=../../../../../etc/passwd
echo "$(dirname $(readlink -e $F))/$(basename $F)"

উৎপাদনের

/etc/passwd

আপনি যদি নিরাপদে কোনও ডিরেক্টরিকে লক্ষ্য করে থাকেন তবে basenameকিছুই ফেরত পাবেন না এবং আপনি চূড়ান্ত আউটপুটটিতে ডাবল স্ল্যাশ দিয়ে শেষ করবেন।


সঙ্গে চমত্কার এন্ট্রি dirname, readlinkএবং basename। এটি আমাকে প্রতীকী লিঙ্কের নিখুঁত পথ পেতে সহায়তা করেছে - এটির লক্ষ্য নয়।
কেভিনার্পে

যখন আপনি প্রতীকী লিঙ্কগুলিতে ফিরে যেতে চান তখন কাজ করে না (যা করার জন্য আমি যা করতে চাই ...)।
টোমা জ্যাটো - মনিকা

যে অস্তিত্ব নেই সেই পথে আপনি কীভাবে পরম পথ খুঁজে পেতে পারেন?
সিনথেসাইজারপেটেল

@ সাইন্সেসাইজারপ্যাটেল সহজেই ভাবতে পারতাম; যদি আমি থাকি /home/GKFXএবং আমি টাইপ করি touch newfile, তবে আমি এন্টার টিপানোর আগে আপনি কাজ করতে পারবেন যে আমি বোঝাতে চাইছি "create / home / GKFX / newfile", যা এখনও উপস্থিত নেই এমন একটি ফাইলের পরম পথ।
GKFX

25

আমি মনে করি এটি সবচেয়ে বহনযোগ্য:

abspath() {                                               
    cd "$(dirname "$1")"
    printf "%s/%s\n" "$(pwd)" "$(basename "$1")"
    cd "$OLDPWD"
}

যদিও পথটি না থাকলে এটি ব্যর্থ হবে।


3
আবার সিডি করার দরকার নেই। স্ট্যাকওভারফ্লো . com/a/21188136/1504556 দেখুন । আপনার এই পৃষ্ঠার সেরা উত্তর, আইএমএইচও। আগ্রহীদের জন্য লিঙ্কটি এই সমাধান কেন কাজ করে তা একটি ব্যাখ্যা দেয় ।
পিটার

এটি খুব পোর্টেবল নয়, dirnameএটি একটি জিএনইউ কোর ইউটিলিটি, আমি বিশ্বাস করি এমন সব ইউনিক্সের পক্ষে সাধারণ নয়।
einpoklum

@ আইনপোকলুম dirnameএকটি পসিক্স স্ট্যান্ডার্ড ইউটিলিটি, এখানে দেখুন: pubs.opengroup.org/onlinepubs/9699919799/utilities/dirname.html
আর্নেস্ট এ

ওহ Godশ্বর, আপনাকে ধন্যবাদ। আমি ${1##*/}এখন এক দিনের জন্য যে সংস্করণটি ব্যবহার করে তা ঠিক করার চেষ্টা করেছি এবং এখন আমি যে আবর্জনাটিকে এর সাথে প্রতিস্থাপন করেছি basename "$1"তা অবশেষে মনে হচ্ছে / / এ শেষ হওয়া পথগুলি সঠিকভাবে পরিচালনা করছে।
l3l_aze

এনবি, এটি শেষ হওয়ার পথে সঠিক কাজটি করে না../..
অ্যালেক্স কভেন্ট্রি

16

realpath সম্ভবত সেরা

তবে ...

প্রাথমিক প্রশ্নটি শুরু করার জন্য খুব বিভ্রান্ত হয়েছিল, যেমনটি বলা হয়েছে যেভাবে প্রশ্নের সাথে খারাপ সম্পর্কিত নয় example

নির্বাচিত উত্তরটি প্রকৃতপক্ষে প্রদত্ত উদাহরণটির উত্তর দেয়, এবং শিরোনামের কোনও প্রশ্নেই নয়। প্রথম আদেশটি হ'ল উত্তর (এটি কি সত্য? আমি সন্দেহ করি), এবং '/' ছাড়াই এটি করতে পারত। এবং দ্বিতীয় কমান্ডটি কি করছে তা দেখতে আমি ব্যর্থ।

বেশ কয়েকটি ইস্যু মিশ্রিত:

  • একটি আপেক্ষিক পথের নামকে পরম স্থানে পরিবর্তন করা, এটি যা বোঝায়, সম্ভবত কিছুই নয়। ( সাধারণত আপনি যদি কোনও কমান্ড জারি করেন তবে touch foo/bar, foo/barফাইলটি তৈরির আগে প্যাথনামটি অবশ্যই আপনার জন্য উপস্থিত থাকতে হবে এবং সম্ভবত সংখ্যায় ব্যবহৃত হতে পারে ))

  • বেশ কয়েকটি নিখুঁত পথের নাম থাকতে পারে যা একই ফাইলটিকে (বা সম্ভাব্য ফাইল) বোঝায়, বিশেষত পাথরে প্রতীকী লিঙ্কগুলি (syllinks) এর কারণে, তবে সম্ভবত অন্যান্য কারণে (কোনও ডিভাইস কেবল পঠনযোগ্য হিসাবে দু'বার মাউন্ট করা যেতে পারে)। এই জাতীয় প্রতীকগুলি স্পষ্টতা সমাধান করতে পারে বা নাও করতে পারে।

  • একটি নন-সিমিলিংক ফাইল বা নামের সাথে প্রতীকী লিঙ্কগুলির একটি শৃঙ্খলে পৌঁছে। এটি কীভাবে হয় তার উপর নির্ভর করে এটি একটি নিখুঁত পাথের নাম দিতে পারে বা নাও পারে। এবং কেউ একে একে পরম পথের নাম হিসাবে সমাধান করতে চাইতে পারে না।

readlink fooবিকল্প ব্যতীত কমান্ডটি কেবল তখনই একটি উত্তর দেয় যখন এর যুক্তিটি fooপ্রতীকী লিঙ্ক এবং সেই উত্তরটি সেই সিমিলিংকের মান। অন্য কোনও লিঙ্ক অনুসরণ করা হয় না। উত্তরটি একটি আপেক্ষিক পথ হতে পারে: যা কিছু ছিল সিমিলিংকের যুক্তির।

তবে, readlinkবিকল্পগুলি (-f -e বা -m) রয়েছে যা সমস্ত ফাইলের জন্য কাজ করবে এবং যুক্তিতে প্রমাণিত ফাইলটিকে একটি পরম পথ (কোনও সিমলিঙ্কযুক্ত নয়) দেবে।

এটি এমন কোনও কিছুর জন্য সূক্ষ্মভাবে কাজ করে যা কোনও সিমলিংক নয়, যদিও কেউ হয়তো মধ্যবর্তী চিহ্নগুলি সমাধান না করেই পরম পথ ব্যবহার করতে আগ্রহী desire এটি কমান্ড দ্বারা সম্পন্ন হয়realpath -s foo

কোনও সিমিলিংকের যুক্তির ক্ষেত্রে, readlinkএর বিকল্পগুলি আবার যুক্তির নিখুঁত পথে সমস্ত সিমলিংকগুলি সমাধান করবে, তবে এটিতে যুক্তিটির মান অনুসরণ করে যে সমস্ত প্রতিলিঙ্কের মুখোমুখি হতে পারে সেগুলিও অন্তর্ভুক্ত থাকবে। আপনি এটি চাইবেন না যে আপনি যদি যুক্তির সাথে সংযুক্ত হতে পারে তার চেয়ে বরং যুক্তি সিএমলিংকের কাছে একটি নিখুঁত পথ চান। আবার, যদি fooএকটি সিমিলিংক হয়, realpath -s fooযুক্তি হিসাবে দেওয়া একটি সহ, সিমলিংকগুলি সমাধান না করেই একটি নিখুঁত পথ পাবে।

ছাড়া -sবিকল্প, realpathহিসাবে একই প্রায় কাছাকাছি আছে readlinkকেবল একটি লিঙ্ক মান, সেইসাথে বিভিন্ন অন্যান্য বিষয়ের পড়ার জন্য ব্যতীত। readlinkএটির বিকল্পগুলি কেন রয়েছে তা কেবল আমার কাছে পরিষ্কার নয় , এগুলি আপাতভাবে একটি অনাকাঙ্ক্ষিত রিডানডেন্সি তৈরি করে realpath

ওয়েবে অন্বেষণ আরও কিছু বলতে পারে না, ব্যতীত সিস্টেমগুলির মধ্যে কিছু ভিন্নতা থাকতে পারে।

উপসংহার: realpathকমপক্ষে এখানে অনুরোধ করা ব্যবহারের জন্য সর্বাধিক নমনীয়তা সহ ব্যবহার করার জন্য সেরা কমান্ড।


10

আমার প্রিয় সমাধানটি ছিল একটি কারণ এটি অন্যান্য ইউটিলিটি উপস্থিতিতে (coreutils প্যাকেজ) পরোক্ষভাবে করা হয়নি @EugenKonkov দ্বারা।

তবে এটি আপেক্ষিক পথে ব্যর্থ হয়েছে ""। এবং "..", সুতরাং এখানে এই বিশেষ ক্ষেত্রে পরিচালনা করার জন্য কিছুটা উন্নত সংস্করণ দেওয়া আছে।

যদিও ব্যবহারকারীর cdআপেক্ষিক পথের পিতৃ ডিরেক্টরিতে প্রবেশের অনুমতি না থাকলে এটি এখনও ব্যর্থ হয় ।

#! /bin/sh

# Takes a path argument and returns it as an absolute path. 
# No-op if the path is already absolute.
function to-abs-path {
    local target="$1"

    if [ "$target" == "." ]; then
        echo "$(pwd)"
    elif [ "$target" == ".." ]; then
        echo "$(dirname "$(pwd)")"
    else
        echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
    fi
}

7

ইউজেনের উত্তর আমার পক্ষে বেশ কার্যকর হয়নি তবে এটি হয়েছে:

    absolute="$(cd $(dirname \"$file\"); pwd)/$(basename \"$file\")"

পার্শ্ব নোট, আপনার বর্তমান কাজ ডিরেক্টরিটি প্রভাবিত নয়।


বিজ্ঞপ্তি: এটি স্ক্রিপ্ট। যেখানে $ 1 এর পক্ষে প্রথম যুক্তি
ইউজেন কনকভ

5

সবচেয়ে ভাল সমাধান, ইমো, এখানে পোস্ট করা একটি: https://stackoverflow.com/a/3373298/9724628

এটি অজগর কাজ করতে প্রয়োজন, কিন্তু এটি সমস্ত বা বেশিরভাগ প্রান্তের কেসগুলি আবৃত করে এবং খুব বহনযোগ্য সমাধান হতে পারে বলে মনে হয়।

  1. সমাধানের প্রতীকগুলি সহ:
python -c "import os,sys; print(os.path.realpath(sys.argv[1]))" path/to/file
  1. বা এটি ছাড়া:
python -c "import os,sys; print(os.path.abspath(sys.argv[1]))" path/to/file

3

এর ক্ষেত্রে findসন্ধানের জন্য এটির জন্য নিখুঁত পথ দেওয়া সম্ভবত সবচেয়ে সহজ, যেমন:

find /etc
find `pwd`/subdir_of_current_dir/ -type f

3

আপনি যদি ম্যাক ওএস এক্সে ব্যাশ ব্যবহার করছেন যা রিয়েলপথের অস্তিত্বই নেই বা এর পাঠ্য লিঙ্কটি চূড়ান্ত পথে মুদ্রণ করতে পারে না, তবে এটি মুদ্রণের জন্য আপনার নিজের সংস্করণ কোড করার বিকল্প থাকতে পারে। আমার বাস্তবায়ন এখানে:

(খাঁটি বাশ)

abspath(){
  local thePath
  if [[ ! "$1" =~ ^/ ]];then
    thePath="$PWD/$1"
  else
    thePath="$1"
  fi
  echo "$thePath"|(
  IFS=/
  read -a parr
  declare -a outp
  for i in "${parr[@]}";do
    case "$i" in
    ''|.) continue ;;
    ..)
      len=${#outp[@]}
      if ((len==0));then
        continue
      else
        unset outp[$((len-1))] 
      fi
      ;;
    *)
      len=${#outp[@]}
      outp[$len]="$i"
      ;;
    esac
  done
  echo /"${outp[*]}"
)
}

(গাওক ব্যবহার করুন)

abspath_gawk() {
    if [[ -n "$1" ]];then
        echo $1|gawk '{
            if(substr($0,1,1) != "/"){
                path = ENVIRON["PWD"]"/"$0
            } else path = $0
            split(path, a, "/")
            n = asorti(a, b,"@ind_num_asc")
            for(i in a){
                if(a[i]=="" || a[i]=="."){
                    delete a[i]
                }
            }
            n = asorti(a, b, "@ind_num_asc")
            m = 0
            while(m!=n){
                m = n
                for(i=1;i<=n;i++){
                    if(a[b[i]]==".."){
                        if(b[i-1] in a){
                            delete a[b[i-1]]
                            delete a[b[i]]
                            n = asorti(a, b, "@ind_num_asc")
                            break
                        } else exit 1
                    }
                }
            }
            n = asorti(a, b, "@ind_num_asc")
            if(n==0){
                printf "/"
            } else {
                for(i=1;i<=n;i++){
                    printf "/"a[b[i]]
                }
            }
        }'
    fi
}

(খাঁটি বিএসডি অ্যাডক)

#!/usr/bin/env awk -f
function abspath(path,    i,j,n,a,b,back,out){
  if(substr(path,1,1) != "/"){
    path = ENVIRON["PWD"]"/"path
  }
  split(path, a, "/")
  n = length(a)
  for(i=1;i<=n;i++){
    if(a[i]==""||a[i]=="."){
      continue
    }
    a[++j]=a[i]
  }
  for(i=j+1;i<=n;i++){
    delete a[i]
  }
  j=0
  for(i=length(a);i>=1;i--){
    if(back==0){
      if(a[i]==".."){
        back++
        continue
      } else {
        b[++j]=a[i]
      }
    } else {
      if(a[i]==".."){
        back++
        continue
      } else {
        back--
        continue
      }
    }
  }
  if(length(b)==0){
    return "/"
  } else {
    for(i=length(b);i>=1;i--){
      out=out"/"b[i]
    }
    return out
  }
}

BEGIN{
  if(ARGC>1){
    for(k=1;k<ARGC;k++){
      print abspath(ARGV[k])
    }
    exit
  }
}
{
  print abspath($0)
}

উদাহরণ:

$ abspath I/am/.//..//the/./god/../of///.././war
/Users/leon/I/the/war

1

তারা find $PWD(বাশে) বাদে যা বলেছিল find ~+তা কিছুটা সুবিধাজনক।


1

@ আর্নেস্ট-এ-এর উত্তরের মতো তবে কোনও $OLDPWDনতুন ফাংশনকে প্রভাবিত বা সংজ্ঞায়িত না করে আপনি একটি সাব-শেল নষ্ট করতে পারেন(cd <path>; pwd)

$ pwd
/etc/apache2
$ cd ../cups 
$ cd -
/etc/apache2
$ (cd ~/..; pwd)
/Users
$ cd -
/etc/cups


1
echo "mydir/doc/ mydir/usoe ./mydir/usm" |  awk '{ split($0,array," "); for(i in array){ system("cd "array[i]" && echo $PWD") } }'

3
এই কোড স্নিপেটের জন্য আপনাকে ধন্যবাদ, যা কিছু সীমিত স্বল্পমেয়াদী সহায়তা সরবরাহ করতে পারে। একটি সঠিক ব্যাখ্যা কেন এটি সমস্যার একটি ভাল সমাধান, তা দেখিয়ে তার দীর্ঘমেয়াদী মানকে ব্যাপকভাবে উন্নত করবে এবং ভবিষ্যতে পাঠকদের আরও অন্যান্য অনুরূপ প্রশ্নের সাথে আরও দরকারী করে তুলবে। আপনার অনুমানগুলি সহ কিছু ব্যাখ্যা যুক্ত করতে দয়া করে আপনার উত্তরটি সম্পাদনা করুন।
টবি স্পিড

1

@ আর্নেস্ট-এর পরিবর্তে সুন্দর সংস্করণে উন্নতি:

absolute_path() {
    cd "$(dirname "$1")"
    case $(basename $1) in
        ..) echo "$(dirname $(pwd))";;
        .)  echo "$(pwd)";;
        *)  echo "$(pwd)/$(basename $1)";;
    esac
}

সঠিকভাবে ক্ষেত্রে যেখানে পথের শেষ উপাদান সঙ্গে এই চুক্তি .., যে ক্ষেত্রে "$(pwd)/$(basename "$1")"মধ্যে @ আর্নেস্ট-একটি এর উত্তর হিসাবে মাধ্যমে আসবে accurate_sub_path/spurious_subdirectory/..


0

আপনি যদি কোনও আপেক্ষিক পাথযুক্ত একটি ভেরিয়েবলকে পরম পথে রূপান্তর করতে চান তবে এটি কাজ করে:

   dir=`cd "$dir"`

"সিডি" ওয়ার্কিং ডিরেক্টরি পরিবর্তন না করে প্রতিধ্বনিত হয়, কারণ এখানে একটি সাব-শেলতে কার্যকর করা হয়েছে।


2
Bash-4.3-p46 এ, এটি কাজ করে না: আমি যখন চালাচ্ছি তখন শেলটি একটি খালি লাইনটি প্রিন্ট করেdir=`cd ".."` && echo $dir
মাইকেল মাইকেল

0

এটি অন্য সকলের একটি শৃঙ্খলিত সমাধান, উদাহরণস্বরূপ, যখন realpathব্যর্থ হয়, হয় এটি ইনস্টল না হওয়ার কারণে বা এটি ত্রুটি কোড সহ প্রস্থান করে, তারপরে, সঠিক সমাধান না পাওয়া পর্যন্ত পরবর্তী সমাধানটি চেষ্টা করা হয়।

#!/bin/bash

function getabsolutepath() {
    local target;
    local changedir;
    local basedir;
    local firstattempt;

    target="${1}";
    if [ "$target" == "." ];
    then
        printf "%s" "$(pwd)";

    elif [ "$target" == ".." ];
    then
        printf "%s" "$(dirname "$(pwd)")";

    else
        changedir="$(dirname "${target}")" && basedir="$(basename "${target}")" && firstattempt="$(cd "${changedir}" && pwd)" && printf "%s/%s" "${firstattempt}" "${basedir}" && return 0;
        firstattempt="$(readlink -f "${target}")" && printf "%s" "${firstattempt}" && return 0;
        firstattempt="$(realpath "${target}")" && printf "%s" "${firstattempt}" && return 0;

        # If everything fails... TRHOW PYTHON ON IT!!!
        local fullpath;
        local pythoninterpreter;
        local pythonexecutables;
        local pythonlocations;

        pythoninterpreter="python";
        declare -a pythonlocations=("/usr/bin" "/bin");
        declare -a pythonexecutables=("python" "python2" "python3");

        for path in "${pythonlocations[@]}";
        do
            for executable in "${pythonexecutables[@]}";
            do
                fullpath="${path}/${executable}";

                if [[ -f "${fullpath}" ]];
                then
                    # printf "Found ${fullpath}\\n";
                    pythoninterpreter="${fullpath}";
                    break;
                fi;
            done;

            if [[ "${pythoninterpreter}" != "python" ]];
            then
                # printf "Breaking... ${pythoninterpreter}\\n"
                break;
            fi;
        done;

        firstattempt="$(${pythoninterpreter} -c "import os, sys; print( os.path.abspath( sys.argv[1] ) );" "${target}")" && printf "%s" "${firstattempt}" && return 0;
        # printf "Error: Could not determine the absolute path!\\n";
        return 1;
    fi
}

printf "\\nResults:\\n%s\\nExit: %s\\n" "$(getabsolutepath "./asdfasdf/ asdfasdf")" "${?}"

0

আপনি যে কোনও আপেক্ষিক পাথ $ লাইনের জন্য ব্যাশ স্ট্রিং বিকল্প ব্যবহার করতে পারেন:

line=$(echo ${line/#..\//`cd ..; pwd`\/})
line=$(echo ${line/#.\//`pwd`\/})
echo $line

মৌলিক ফ্রন্ট-অফ-স্ট্রিং প্রতিস্থাপনটি সূত্রটি অনুসরণ করে
{{স্ট্রিং / # স্ট্রিং / রিপ্লেসমেন্ট}
যা এখানে ভাল আলোচনা করা হয়েছে: https://www.tldp.org/LDP/abs/html/string-manipulation.html

\চরিত্র negates /যখন আমরা এটা স্ট্রিংটি আমরা খুঁজে / প্রতিস্থাপন অংশ হতে চাই।


0

আমি ম্যাক ওএস ক্যাটালিনা, উবুন্টু 16 এবং সেন্টোস 7 এর মধ্যে খুব সুন্দরভাবে বহনযোগ্য কোনও সমাধান খুঁজে পাচ্ছিলাম না, তাই আমি পাইথন ইনলাইন দিয়ে এটি করার সিদ্ধান্ত নিয়েছিলাম এবং এটি আমার ব্যাশ স্ক্রিপ্টগুলির জন্য ভাল কাজ করেছে।

to_abs_path() {
  python -c "import os; print os.path.abspath('$1')"
}

to_abs_path "/some_path/../secrets"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.