আমি বর্তমানে ওএস এক্স-তে চলমান স্ক্রিপ্টের নিখুঁত পথটি পাওয়ার চেষ্টা করছি।
আমি অনেক জবাব চাইছি readlink -f $0
। তবে যেহেতু ওএস এক্স এর readlink
বিএসডি'র মতো, তাই এটি ঠিক কাজ করে না (এটি জিএনইউর সংস্করণে কাজ করে)।
এর বাইরে কি কোনও সমাধান আছে?
আমি বর্তমানে ওএস এক্স-তে চলমান স্ক্রিপ্টের নিখুঁত পথটি পাওয়ার চেষ্টা করছি।
আমি অনেক জবাব চাইছি readlink -f $0
। তবে যেহেতু ওএস এক্স এর readlink
বিএসডি'র মতো, তাই এটি ঠিক কাজ করে না (এটি জিএনইউর সংস্করণে কাজ করে)।
এর বাইরে কি কোনও সমাধান আছে?
$( cd "$(dirname "$0")" ; pwd -P )
উত্তর:
একটি realpath()
সি ফাংশন রয়েছে যা কাজটি করবে, তবে আমি কমান্ড-লাইনে উপলভ্য কিছুই দেখছি না। এখানে একটি দ্রুত এবং নোংরা প্রতিস্থাপন:
#!/bin/bash
realpath() {
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}
realpath "$0"
এটি পথ দিয়ে শব্দটি মুদ্রণ করে যদি এটি দিয়ে শুরু হয় /
। যদি তা না হয় তবে এটি অবশ্যই একটি আপেক্ষিক পথ হতে পারে, সুতরাং এটি $PWD
সামনের দিকে এগিয়ে যায়। #./
অংশ বন্ধ রেখাচিত্রমালা ./
সামনে থেকে $1
।
realpath ../something
রিটার্ন$PWD/../something
command -v realpath >/dev/null 2>&1 || realpath() { ... }
এই তিনটি সহজ পদক্ষেপ এটি এবং অন্যান্য অনেকগুলি ওএস এক্স সমস্যা সমাধান করতে চলেছে:
brew install coreutils
grealpath .
(3) কেবলমাত্র পরিবর্তিত হতে পারে realpath
, দেখুন (2) আউটপুট
$( cd "$(dirname "$0")" ; pwd -P )
আমার পক্ষে কার্যকর কাজ করে।
XXX
এবং কিছু থাকে cd xxx
তবে pwd
তা ফিরে আসবে .../xxx
। এই উত্তরটি বাদে উপরের সমস্ত সমাধান ফিরে আসে xxx
যখন আপনি আসলে যা চান তা XXX
। ধন্যবাদ!
realpath
, তবে আপনার যখন অবশ্যই অন্যান্য আইটেমগুলির প্রয়োজন হবে তখন কী হবে coreutils
? বাশগুলিতেও সেই ফাংশনগুলি আবার লিখুন? : পি
উঃ আমি পূর্ববর্তী উত্তরগুলি কয়েকটি কারণে কিছুটা চাওয়া পেয়েছি: বিশেষত, তারা একাধিক স্তরের প্রতীকী লিঙ্কগুলি সমাধান করে না এবং তারা অত্যন্ত "বাশ-ওয়াই"। যদিও মূল প্রশ্নটি স্পষ্টভাবে একটি "বাশ স্ক্রিপ্ট" চেয়েছে, এটি ম্যাক ওএস এক্সের বিএসডি-জাতীয়, নন-জিএনইউরও উল্লেখ করেছে readlink
। সুতরাং এখানে কিছু যুক্তিসঙ্গত বহনযোগ্যতার একটি চেষ্টা করা হয়েছে (আমি এটি 'sh' এবং ড্যাশ হিসাবে বাশ দিয়ে পরীক্ষা করেছি), প্রতারণামূলক লিঙ্কগুলির একটি স্বেচ্ছাসেবী সংখ্যার সমাধান করে; এবং এটি পাথ (গুলি) -এর সাদা অংশের সাথেও কাজ করা উচিত, যদিও আমি ব্যবহারের বিষয়ে নিশ্চিত নই যদি সাদা স্থান ইউটিলিটির নিজস্ব নামটি থাকে তবে তাই, ওম, এড়ানো যাবে?
#!/bin/sh
realpath() {
OURPWD=$PWD
cd "$(dirname "$1")"
LINK=$(readlink "$(basename "$1")")
while [ "$LINK" ]; do
cd "$(dirname "$LINK")"
LINK=$(readlink "$(basename "$1")")
done
REALPATH="$PWD/$(basename "$1")"
cd "$OURPWD"
echo "$REALPATH"
}
realpath "$@"
আশা করি কারও কারও কাজে লাগতে পারে।
local
বিশ্বব্যাপী নেমস্পেসকে দূষিত না করতে ফাংশনের অভ্যন্তরে সংজ্ঞায়িত পরিবর্তনশীলগুলির জন্য ব্যবহার করার পরামর্শ দেব । যেমন local OURPWD=...
। কমপক্ষে ব্যাশের জন্য কাজ করে।
BASENAME=$(basename "$LINK")
এবং এটি দ্বিতীয় লিঙ্ক সেটার এবং রিয়েলপথ সেটারে ব্যবহার করা ভাল
..
পিতামাতাকে রেফগুলি realpath
দেয়। হোমব্রু coreutils
ইনস্টল করার ln -s /var/log /tmp/linkexample
পরে , চেষ্টা করুন realpath /tmp/linkexample/../
; এই প্রিন্ট /private/var
। তবে এর /tmp/linkexample/..
পরিবর্তে আপনার ফাংশনটি উত্পন্ন করে, কারণ ..
এটি কোনও সিমলিংক নয়।
পাইথন সমাধানের আরও একটি কমান্ড-লাইন-বান্ধব রূপ:
python -c "import os; print(os.path.realpath('$1'))"
python -c "import os; import sys; print(os.path.realpath(sys.argv[1]))"
আমি সিস্টেম বিধানের স্ক্রিপ্টে ব্যবহারের জন্য সমাধান খুঁজছিলাম, যেমন হোমব্রুও ইনস্টল হওয়ার আগেই চালানো। সঠিক সমাধানের অভাবে আমি কেবলমাত্র ক্রস প্ল্যাটফর্মের ভাষায় টাস্কটি অফলোড করব, যেমন পার্ল:
script_abspath=$(perl -e 'use Cwd "abs_path"; print abs_path(@ARGV[0])' -- "$0")
প্রায়শই আমরা আসলে যা চাই তা হ'ল সমন্বিত ডিরেক্টরি:
here=$(perl -e 'use File::Basename; use Cwd "abs_path"; print dirname(abs_path(@ARGV[0]));' -- "$0")
FULLPATH=$(perl -e "use Cwd 'abs_path'; print abs_path('$0')")
। এর বিরুদ্ধে কোন কারণ?
''
বুলেট-প্রমাণ নয়। $0
উদাহরণস্বরূপ, যদি একটি একক উদ্ধৃতি থাকে তবে এটি ভেঙে যায় । খুব সাধারণ উদাহরণ: আপনার সংস্করণটি চেষ্টা করে দেখুন /tmp/'/test.sh
এবং /tmp/'/test.sh
এটির পুরো পথে কল করুন ।
/tmp/'.sh
,।
যেহেতু একটি রিয়েলপথ রয়েছে যেমন অন্যরা উল্লেখ করেছে:
// realpath.c
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char* argv[])
{
if (argc > 1) {
for (int argIter = 1; argIter < argc; ++argIter) {
char *resolved_path_buffer = NULL;
char *result = realpath(argv[argIter], resolved_path_buffer);
puts(result);
if (result != NULL) {
free(result);
}
}
}
return 0;
}
মেকফাইল:
#Makefile
OBJ = realpath.o
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)
realpath: $(OBJ)
gcc -o $@ $^ $(CFLAGS)
তারপরে সংকলন করুন make
এবং এর সাথে একটি নরম লিঙ্কে রাখুন:
ln -s $(pwd)/realpath /usr/local/bin/realpath
gcc realpath.c -o /usr/local/bin/realpath
?
/usr/local/bin
abs_path () {
echo "$(cd $(dirname "$1");pwd)/$(basename "$1")"
}
dirname
এর ডিরেক্টরি নাম /path/to/file
, যেমন দেবে/path/to
।
cd /path/to; pwd
পথটি নিখুঁত নিশ্চিত করে is
basename
কেবলমাত্র ফাইলের নাম দেবে /path/to/file
, যেমন file
।
আপনি উপরের দেখতে যেমন দেখতে পাচ্ছেন, আমি প্রায় 6 মাস আগে এটিতে একটি শট নিয়েছি। আমি নিজেকে সম্পূর্ণরূপে ভুলে গেছি যতক্ষণ না আমি নিজেকে আবার অনুরূপ জিনিসের প্রয়োজনে পেয়েছি। আমি পুরোপুরি হতবাক হয়ে গিয়েছিলামঠিক কতটা উদ্বেগজনক তা দেখে হয়ে গিয়েছিলাম; আমি নিজেকে প্রায় এক বছর ধরে নিবিড়ভাবে কোড করতে শিখিয়েছি, তবে আমার প্রায়শই মনে হয় যখন জিনিসগুলি সবচেয়ে খারাপ সময়ে হয় তখন আমি কিছুই শিখি না।
আমি উপরের 'সমাধান' সরিয়ে ফেলব, তবে আমি সত্যিই এটি পছন্দ করি গত কয়েক মাসে আমি সত্যিই কতটা শিখলাম তার রেকর্ড হওয়া।
কিন্তু আমার দ্বিমত আছে. আমি গত রাতে বসে সমস্ত কাজ করেছি। মন্তব্যে ব্যাখ্যা যথেষ্ট হওয়া উচিত। আমি যে অনুলিপিটি নিয়ে কাজ করে চলেছি তা যদি আপনি ট্র্যাক করতে চান তবে আপনি এই সূচনাটি অনুসরণ করতে পারেন। এটি সম্ভবত আপনার যা প্রয়োজন তা করে।
#!/bin/sh # dash bash ksh # !zsh (issues). G. Nixon, 12/2013. Public domain.
## 'linkread' or 'fullpath' or (you choose) is a little tool to recursively
## dereference symbolic links (ala 'readlink') until the originating file
## is found. This is effectively the same function provided in stdlib.h as
## 'realpath' and on the command line in GNU 'readlink -f'.
## Neither of these tools, however, are particularly accessible on the many
## systems that do not have the GNU implementation of readlink, nor ship
## with a system compiler (not to mention the requisite knowledge of C).
## This script is written with portability and (to the extent possible, speed)
## in mind, hence the use of printf for echo and case statements where they
## can be substituded for test, though I've had to scale back a bit on that.
## It is (to the best of my knowledge) written in standard POSIX shell, and
## has been tested with bash-as-bin-sh, dash, and ksh93. zsh seems to have
## issues with it, though I'm not sure why; so probably best to avoid for now.
## Particularly useful (in fact, the reason I wrote this) is the fact that
## it can be used within a shell script to find the path of the script itself.
## (I am sure the shell knows this already; but most likely for the sake of
## security it is not made readily available. The implementation of "$0"
## specificies that the $0 must be the location of **last** symbolic link in
## a chain, or wherever it resides in the path.) This can be used for some
## ...interesting things, like self-duplicating and self-modifiying scripts.
## Currently supported are three errors: whether the file specified exists
## (ala ENOENT), whether its target exists/is accessible; and the special
## case of when a sybolic link references itself "foo -> foo": a common error
## for beginners, since 'ln' does not produce an error if the order of link
## and target are reversed on the command line. (See POSIX signal ELOOP.)
## It would probably be rather simple to write to use this as a basis for
## a pure shell implementation of the 'symlinks' util included with Linux.
## As an aside, the amount of code below **completely** belies the amount
## effort it took to get this right -- but I guess that's coding for you.
##===-------------------------------------------------------------------===##
for argv; do :; done # Last parameter on command line, for options parsing.
## Error messages. Use functions so that we can sub in when the error occurs.
recurses(){ printf "Self-referential:\n\t$argv ->\n\t$argv\n" ;}
dangling(){ printf "Broken symlink:\n\t$argv ->\n\t"$(readlink "$argv")"\n" ;}
errnoent(){ printf "No such file: "$@"\n" ;} # Borrow a horrible signal name.
# Probably best not to install as 'pathfull', if you can avoid it.
pathfull(){ cd "$(dirname "$@")"; link="$(readlink "$(basename "$@")")"
## 'test and 'ls' report different status for bad symlinks, so we use this.
if [ ! -e "$@" ]; then if $(ls -d "$@" 2>/dev/null) 2>/dev/null; then
errnoent 1>&2; exit 1; elif [ ! -e "$@" -a "$link" = "$@" ]; then
recurses 1>&2; exit 1; elif [ ! -e "$@" ] && [ ! -z "$link" ]; then
dangling 1>&2; exit 1; fi
fi
## Not a link, but there might be one in the path, so 'cd' and 'pwd'.
if [ -z "$link" ]; then if [ "$(dirname "$@" | cut -c1)" = '/' ]; then
printf "$@\n"; exit 0; else printf "$(pwd)/$(basename "$@")\n"; fi; exit 0
fi
## Walk the symlinks back to the origin. Calls itself recursivly as needed.
while [ "$link" ]; do
cd "$(dirname "$link")"; newlink="$(readlink "$(basename "$link")")"
case "$newlink" in
"$link") dangling 1>&2 && exit 1 ;;
'') printf "$(pwd)/$(basename "$link")\n"; exit 0 ;;
*) link="$newlink" && pathfull "$link" ;;
esac
done
printf "$(pwd)/$(basename "$newlink")\n"
}
## Demo. Install somewhere deep in the filesystem, then symlink somewhere
## else, symlink again (maybe with a different name) elsewhere, and link
## back into the directory you started in (or something.) The absolute path
## of the script will always be reported in the usage, along with "$0".
if [ -z "$argv" ]; then scriptname="$(pathfull "$0")"
# Yay ANSI l33t codes! Fancy.
printf "\n\033[3mfrom/as: \033[4m$0\033[0m\n\n\033[1mUSAGE:\033[0m "
printf "\033[4m$scriptname\033[24m [ link | file | dir ]\n\n "
printf "Recursive readlink for the authoritative file, symlink after "
printf "symlink.\n\n\n \033[4m$scriptname\033[24m\n\n "
printf " From within an invocation of a script, locate the script's "
printf "own file\n (no matter where it has been linked or "
printf "from where it is being called).\n\n"
else pathfull "$@"
fi
..
পিতামাতার রেফারেন্সগুলির আগে চিহ্নগুলি সমাধান করে না ; উদাহরণস্বরূপ সিমলিংকটি যেদিকেই নির্দেশ করে তার পিতামাতার পরিবর্তে /foo/link_to_other_directory/..
সমাধান করা হয়। এবং প্রতিটি পাথ উপাদানটিকে মূল থেকে শুরু করে সমাধান করুন এবং প্রসেন্ডিং লিঙ্ক লক্ষ্যগুলি আপডেট করা বাকিগুলিতে এখনও আপডেট করা হচ্ছে। আমি এই যুক্তিটিকে পুনরায় প্রয়োগ করার জন্য এই প্রশ্নের উত্তর যুক্ত করেছি। /foo
/foo/link_to_other_directory
readlink -f
realpath
ম্যাক ওএস এক্স এর জন্য রিয়েলপথ
realpath() {
path=`eval echo "$1"`
folder=$(dirname "$path")
echo $(cd "$folder"; pwd)/$(basename "$path");
}
সম্পর্কিত পাথ সহ উদাহরণ:
realpath "../scripts/test.sh"
হোম ফোল্ডারের সাথে উদাহরণ
realpath "~/Test/../Test/scripts/test.sh"
..
করলে সঠিক উত্তর পাওয়া যায় না, তাই আমি প্রদত্ত পথটি কোনও ডিরেক্টরি কিনা তা আমি একটি চেক যুক্ত করেছি: if test -d $path ; then echo $(cd "$path"; pwd) ; else [...]
"$(dirname $(dirname $(realpath $0)))"
কাজ করে, তাই অন্য কিছুর প্রয়োজন ...
echo
এছাড়াও perpetrated করা উচিত নয়।
..
পিতামাতার রেফারেন্সগুলি সমাধান করে, পরে নয়; homebrew সঙ্গে এই চেষ্টা ইনস্টল সঙ্গে লিঙ্ক তৈরি তারপর চালানো ; এই প্রিন্ট । তবে এর পরিবর্তে আপনার ফাংশনটি উত্পাদিত হয়, কারণ এখনও সিডির পরে দেখায় । coreutils
ln -s /var/log /tmp/linkexample
realpath /tmp/linkexample/../
/private/var
/tmp/linkexample/..
pwd
/tmp/linkexample
ম্যাকোস-এ, আমি একমাত্র সমাধানটি খুঁজে পেয়েছি যা নির্ভরযোগ্যভাবে সিমলিংকগুলি পরিচালনা করে তা হ'ল ব্যবহার করে realpath
। যেহেতু এটির প্রয়োজন হয় brew install coreutils
, আমি কেবলমাত্র এই পদক্ষেপটি স্বয়ংক্রিয় করেছি। আমার বাস্তবায়নটি এরকম দেখাচ্ছে:
#!/usr/bin/env bash
set -e
if ! which realpath >&/dev/null; then
if ! which brew >&/dev/null; then
msg="ERROR: This script requires brew. See https://brew.sh for installation instructions."
echo "$(tput setaf 1)$msg$(tput sgr0)" >&2
exit 1
fi
echo "Installing coreutils/realpath"
brew install coreutils >&/dev/null
fi
thisDir=$( dirname "`realpath "$0"`" )
echo "This script is run from \"$thisDir\""
এই ত্রুটিগুলি যদি তারা brew
ইনস্টল না করে থাকে তবে আপনি বিকল্পভাবে এটি ইনস্টল করতে পারেন। নেট থেকে নির্বিচারে রুবি কোডটি কার্ল করে দেয় এমন কিছু স্বয়ংক্রিয় করতে আমি কেবল স্বাচ্ছন্দ্য বোধ করি না।
নোট করুন যে এটি ওলেগ মিখিভের উত্তরের একটি স্বয়ংক্রিয় প্রকরণ ।
এই সমাধানগুলির যে কোনও একটির একটি ভাল পরীক্ষা হ'ল:
ln -s
সেই ফাইলটিতে syMLink ( ) দিনসমাধানটি কি সিমলিংকে সম্মানজনক করে এবং আপনাকে মূল ডিরেক্টরি দেয়? যদি তাই হয়, এটি কাজ করে।
আমি প্রয়োজন realpath
OS X এর উপর প্রতিস্থাপন, যেটা symlinks এবং পিতা বা মাতা রেফারেন্স সঙ্গে পাথ সঠিকভাবে পরিচালনা ঠিক readlink -f
হায় । এর মধ্যে পিতামাতার রেফারেন্সগুলি সমাধান করার আগে পাথগুলিতে সমাধান প্রতীকগুলি অন্তর্ভুক্ত রয়েছে ; উদাহরণস্বরূপ আপনি যদি হোমব্রিউ coreutils
বোতলটি ইনস্টল করেন তবে চালান:
$ ln -s /var/log/cups /tmp/linkeddir # symlink to another directory
$ greadlink -f /tmp/linkeddir/.. # canonical path of the link parent
/private/var/log
নোট যা পিতামাতার দির রেফারেন্সটি readlink -f
সমাধান /tmp/linkeddir
করার আগে সমাধান করেছে ..
। অবশ্যই readlink -f
ম্যাকের কোনও নেই ।
সুতরাং বাশ বাস্তবায়নের অংশ হিসাবে realpath
আমি জিএনউলিব canonicalize_filename_mode(path, CAN_ALL_BUT_LAST)
ফাংশন কলটি কি করে তা পুনরায় প্রয়োগ করে , ৩.২ বাশে; এটি জিএনইউ করে ফাংশন কল readlink -f
:
# shellcheck shell=bash
set -euo pipefail
_contains() {
# return true if first argument is present in the other arguments
local elem value
value="$1"
shift
for elem in "$@"; do
if [[ $elem == "$value" ]]; then
return 0
fi
done
return 1
}
_canonicalize_filename_mode() {
# resolve any symlink targets, GNU readlink -f style
# where every path component except the last should exist and is
# resolved if it is a symlink. This is essentially a re-implementation
# of canonicalize_filename_mode(path, CAN_ALL_BUT_LAST).
# takes the path to canonicalize as first argument
local path result component seen
seen=()
path="$1"
result="/"
if [[ $path != /* ]]; then # add in current working dir if relative
result="$PWD"
fi
while [[ -n $path ]]; do
component="${path%%/*}"
case "$component" in
'') # empty because it started with /
path="${path:1}" ;;
.) # ./ current directory, do nothing
path="${path:1}" ;;
..) # ../ parent directory
if [[ $result != "/" ]]; then # not at the root?
result="${result%/*}" # then remove one element from the path
fi
path="${path:2}" ;;
*)
# add this component to the result, remove from path
if [[ $result != */ ]]; then
result="$result/"
fi
result="$result$component"
path="${path:${#component}}"
# element must exist, unless this is the final component
if [[ $path =~ [^/] && ! -e $result ]]; then
echo "$1: No such file or directory" >&2
return 1
fi
# if the result is a link, prefix it to the path, to continue resolving
if [[ -L $result ]]; then
if _contains "$result" "${seen[@]+"${seen[@]}"}"; then
# we've seen this link before, abort
echo "$1: Too many levels of symbolic links" >&2
return 1
fi
seen+=("$result")
path="$(readlink "$result")$path"
if [[ $path = /* ]]; then
# if the link is absolute, restart the result from /
result="/"
elif [[ $result != "/" ]]; then
# otherwise remove the basename of the link from the result
result="${result%/*}"
fi
elif [[ $path =~ [^/] && ! -d $result ]]; then
# otherwise all but the last element must be a dir
echo "$1: Not a directory" >&2
return 1
fi
;;
esac
done
echo "$result"
}
এটিতে বিজ্ঞপ্তিযুক্ত সিমলিংক সনাক্তকরণ অন্তর্ভুক্ত রয়েছে, যদি একই (মধ্যস্থতাকারী) পথটি দু'বার দেখা হয় তবে প্রস্থান করা হচ্ছে।
আপনার যা প্রয়োজন তা যদি হয় readlink -f
তবে উপরের হিসাবে আপনি ব্যবহার করতে পারেন:
readlink() {
if [[ $1 != -f ]]; then # poor-man's option parsing
# delegate to the standard readlink command
command readlink "$@"
return
fi
local path result seenerr
shift
seenerr=
for path in "$@"; do
# by default readlink suppresses error messages
if ! result=$(_canonicalize_filename_mode "$path" 2>/dev/null); then
seenerr=1
continue
fi
echo "$result"
done
if [[ $seenerr ]]; then
return 1;
fi
}
কারণ realpath
, আমারও প্রয়োজন --relative-to
এবং --relative-base
সমর্থন ছিল, যা আপনাকে ক্যানোনিকালাইজ করার পরে আপেক্ষিক পথ দেয়:
_realpath() {
# GNU realpath replacement for bash 3.2 (OS X)
# accepts --relative-to= and --relative-base options
# and produces canonical (relative or absolute) paths for each
# argument on stdout, errors on stderr, and returns 0 on success
# and 1 if at least 1 path triggered an error.
local relative_to relative_base seenerr path
relative_to=
relative_base=
seenerr=
while [[ $# -gt 0 ]]; do
case $1 in
"--relative-to="*)
relative_to=$(_canonicalize_filename_mode "${1#*=}")
shift 1;;
"--relative-base="*)
relative_base=$(_canonicalize_filename_mode "${1#*=}")
shift 1;;
*)
break;;
esac
done
if [[
-n $relative_to
&& -n $relative_base
&& ${relative_to#${relative_base}/} == "$relative_to"
]]; then
# relative_to is not a subdir of relative_base -> ignore both
relative_to=
relative_base=
elif [[ -z $relative_to && -n $relative_base ]]; then
# if relative_to has not been set but relative_base has, then
# set relative_to from relative_base, simplifies logic later on
relative_to="$relative_base"
fi
for path in "$@"; do
if ! real=$(_canonicalize_filename_mode "$path"); then
seenerr=1
continue
fi
# make path relative if so required
if [[
-n $relative_to
&& ( # path must not be outside relative_base to be made relative
-z $relative_base || ${real#${relative_base}/} != "$real"
)
]]; then
local common_part parentrefs
common_part="$relative_to"
parentrefs=
while [[ ${real#${common_part}/} == "$real" ]]; do
common_part="$(dirname "$common_part")"
parentrefs="..${parentrefs:+/$parentrefs}"
done
if [[ $common_part != "/" ]]; then
real="${parentrefs:+${parentrefs}/}${real#${common_part}/}"
fi
fi
echo "$real"
done
if [[ $seenerr ]]; then
return 1
fi
}
if ! command -v realpath > /dev/null 2>&1; then
# realpath is not available on OSX unless you install the `coreutils` brew
realpath() { _realpath "$@"; }
fi
আমি এই কোডটির জন্য আমার কোড পর্যালোচনা অনুরোধে ইউনিট পরীক্ষা অন্তর্ভুক্ত করেছি ।
কমেন্টারের সাথে কথোপকথনের ভিত্তিতে, আমি সম্মত হয়েছি যে এটি খুব শক্ত এবং কোনও বাস্তবপথ বাস্তবায়নের কোনও ত্রিভুজ উপায় নেই যা উবুন্টুর মতো সম্পূর্ণ আচরণ করে।
তবে নিম্নলিখিত সংস্করণটি, কর্নারের কেসগুলি সেরা উত্তরগুলি পরিচালনা করতে পারে না এবং ম্যাকবুকে আমার প্রাত্যহিক চাহিদা মেটাতে পারে না। এই কোডটি আপনার ~ / .bashrc এ রাখুন এবং মনে রাখবেন:
# 1. if is a dir, try cd and pwd
# 2. if is a file, try cd its parent and concat dir+file
realpath() {
[ "$1" = "" ] && return 1
dir=`dirname "$1"`
file=`basename "$1"`
last=`pwd`
[ -d "$dir" ] && cd $dir || return 1
if [ -d "$file" ];
then
# case 1
cd $file && pwd || return 1
else
# case 2
echo `pwd`/$file | sed 's/\/\//\//g'
fi
cd $last
}
echo
এড়াতে চান । শেলের একটি অনুলিপি অনুলিপি ছাড়াই ঠিক pwd
একই কাজ করে echo $(pwd)
। এছাড়াও, যুক্তিটি উদ্ধৃতি না echo
করা একটি বাগ (আপনি কোনও নেতৃস্থানীয় বা অনুসরণকারী শ্বেতস্পেস, কোনও সংলগ্ন অভ্যন্তরীণ শ্বেত স্পেস অক্ষর হারাবেন এবং ওয়াইল্ডকার্ড প্রসারিত হবে ইত্যাদি)। আরও দেখুন stackoverflow.com/questions/10067266/...
realpath
অস্তিত্বহীন ডিরেক্টরিটির অনুরোধ করবেন তখন অবশ্যই উবুন্টুর আচরণটি বর্তমান ডিরেক্টরিটি মুদ্রণ করা নয় ।
dir=$(dirname "$1"); file=$(basename "$1")
দীর্ঘ-অপ্রচলিত ব্যাকটিক সিনট্যাক্সের পরিবর্তে পছন্দ করুন। আবারও যুক্তির সঠিক উদ্ধৃতি লক্ষ্য করুন notice