স্ক্রিপ্টের ভিতরে বাশ স্ক্রিপ্ট ফাইলটির নাম আমি কীভাবে নির্ধারণ করতে পারি?
আমার স্ক্রিপ্ট যদি ফাইলটিতে থাকে runme.sh
, তবে আমি কীভাবে এটিকে হার্ডকড না করে "আপনি রানমেট.শ চালাচ্ছেন" বার্তাটি প্রদর্শন করতে করব?
স্ক্রিপ্টের ভিতরে বাশ স্ক্রিপ্ট ফাইলটির নাম আমি কীভাবে নির্ধারণ করতে পারি?
আমার স্ক্রিপ্ট যদি ফাইলটিতে থাকে runme.sh
, তবে আমি কীভাবে এটিকে হার্ডকড না করে "আপনি রানমেট.শ চালাচ্ছেন" বার্তাটি প্রদর্শন করতে করব?
উত্তর:
me=`basename "$0"`
একটি সিমিলিংক 1 পড়ার জন্য যা সাধারণত আপনি চান তা নয় (আপনি সাধারণত ব্যবহারকারীকে এভাবে বিভ্রান্ত করতে চান না), চেষ্টা করুন:
me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"
আইএমও, এটি বিভ্রান্তিকর আউটপুট তৈরি করবে। "আমি দৌড়ে গেলাম foo.sh, কিন্তু এটা বলছে যে আমি বার.শ চালাচ্ছি !? অবশ্যই একটি বাগ হতে হবে!" এছাড়াও, আলাদাভাবে নামযুক্ত সিমলিংকগুলির অন্যতম উদ্দেশ্য হ'ল নামটির উপর ভিত্তি করে বিভিন্ন কার্যকারিতা সরবরাহ করা (কিছু প্ল্যাটফর্মগুলিতে জিজিপ এবং গানজিপ মনে করুন)।
1 এটি হ'ল সিমলিংকগুলি সমাধান করার জন্য যে যখন ব্যবহারকারী বাস্তবায়িত হয় foo.sh
যা আসলে একটি সিমলিংক হয় bar.sh
, আপনি bar.sh
বরং পরিবর্তিত নামটি ব্যবহার করতে ইচ্ছুক foo.sh
।
$0
প্রথম উদাহরণে শব্দের বিভাজন সাপেক্ষে ৩ $0
, বেসনেম, রিডলিংক এবং একটি অবস্থানে প্রতিধ্বনিত হয় যা এটি কমান্ড লাইন সুইচ হিসাবে বিবেচনা করতে দেয় । আমি পরিবর্তে me=$(basename -- "$0")
বা আরও বেশি দক্ষতার সাথে পঠনযোগ্যতার ব্যয়ে পরামর্শ দিই me=${0##*/}
,। সিমলিংকের জন্য, me=$(basename -- "$(readlink -f -- "$0")")
gnu ব্যবহারগুলি ধরে ধরে, অন্যথায় এটি খুব দীর্ঘ লিপি হবে যা আমি এখানে লিখব না।
# ------------- লিপি ------------- # # ------------- কল করা ------ ------- #
#!/bin/bash
echo
echo "# arguments called with ----> ${@} "
echo "# \$1 ----------------------> $1 "
echo "# \$2 ----------------------> $2 "
echo "# path to me ---------------> ${0} "
echo "# parent path --------------> ${0%/*} "
echo "# my name ------------------> ${0##*/} "
echo
exit
# পরবর্তী লাইনে লক্ষ্য করুন, প্রথম যুক্তিকে ডাবল, # এবং একক উদ্ধৃতিতে ডাকা হবে, কারণ এতে দুটি শব্দ রয়েছে
$ / বিবিধ / shell_scripts / check_root / show_parms । sh "'হ্যালো সেখানে" " " "উইলিয়াম'"
# ------------- ফলাফল ------------- #
#> যুক্তি দিয়ে ---> 'হ্যালো ওখানে' 'উইলিয়াম' # $ 1 ----------------------> 'হ্যালো আছে' # $ 2 ---- ------------------> 'উইলিয়াম' # আমার কাছে পথ --------------> / বিবিধ / শেল_স্ক্রিপ্ট / চেক_রূট / শো_প্রেম। sh # প্যারেন্ট পাথ -------------> / মিস / শেল_সক্রিপ্টস / চেক_রোট # আমার নাম -----------------> শো_parms.sh
# ------------- শেষ ------------- #
show_params
, অর্থাত্ কোনও বিকল্প বিকল্প ছাড়া নাম?
${0##*/}
। গিটব্যাশ ব্যবহার করে পরীক্ষিত।
বাশ> = 3 সহ নিম্নোক্ত কাজগুলি:
$ ./s
0 is: ./s
BASH_SOURCE is: ./s
$ . ./s
0 is: bash
BASH_SOURCE is: ./s
$ cat s
#!/bin/bash
printf '$0 is: %s\n$BASH_SOURCE is: %s\n' "$0" "$BASH_SOURCE"
dirname $BASE_SOURCE
স্ক্রিপ্টগুলি অবস্থিত ডিরেক্টরিটি পেতে এটি সহজেই ব্যবহার করা যায় ।
$BASH_SOURCE
স্ক্রিপ্ট উত্সাহিত করার সময় সঠিক উত্তর দেয়।
তবে এতে স্ক্রিপ্টগুলি ফাইলের নামটি পেতে কেবলমাত্র পথটি অন্তর্ভুক্ত রয়েছে:
$(basename $BASH_SOURCE)
. <filename> [arguments]
, $0
কলারের শেলের নাম দিতে হবে। কমপক্ষে ওএসএক্স কমপক্ষে নিশ্চিত।
স্ক্রিপ্ট নাম এতে স্পেস থাকে, তাহলে আরো একটি শক্তসমর্থ উপায় ব্যবহার করা "$0"
বা "$(basename "$0")"
- বা MacOS এর উপর: "$(basename \"$0\")"
। এটি কোনওভাবেই নামটি ম্যাঙ্গাল হওয়া বা ব্যাখ্যা করতে বাধা দেয়। সাধারণভাবে, শেলটিতে সর্বদা ডাবল-উদ্ধৃতি পরিবর্তন করা ভাল অনুশীলন।
আপনি যদি পথ ছাড়াই এটি চান তবে আপনি ব্যবহার করতে পারেন ${0##*/}
ক্রিস কনওয়ের উত্তর দেওয়ার জন্য , লিনাক্সে (কমপক্ষে) আপনি এইটি করবেন:
echo $(basename $(readlink -nf $0))
রিডলিংক একটি প্রতীকী লিঙ্কের মান প্রিন্ট করে। যদি এটি প্রতীকী লিঙ্ক না হয় তবে এটি ফাইলটির নাম মুদ্রণ করে। -n এটিকে নতুন লাইন প্রিন্ট না করার জন্য বলে। -ফ এটিকে লিঙ্কটি সম্পূর্ণরূপে অনুসরণ করতে বলে (যদি একটি প্রতীকী লিঙ্ক অন্য লিঙ্কের লিঙ্ক ছিল তবে এটি সেইটিকেও সমাধান করবে)।
ফাইলটি উত্সাহিত হচ্ছে বা স্ক্রিপ্ট হিসাবে চালানো হচ্ছে তা নির্বিশেষে আমি সর্বদা কাজ করতে এই লাইনটি পেয়েছি।
echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
আপনি যদি অনুসরণ করতে চান সিমলিংক ব্যবহার readlink
উপরে উঠে তবে পুনরাবৃত্ত বা অ-পুনরাবৃত্তভাবে।
ওয়ান-লাইনার কাজ করার কারণটি BASH_SOURCE
পরিবেশের পরিবর্তনশীল এবং এর সহযোগী দ্বারা ব্যাখ্যা করা হয়েছে FUNCNAME
।
BASH_SOURCE
একটি অ্যারে ভেরিয়েবল যার সদস্যরা উত্স ফাইল নাম যেখানে FUNCNAME অ্যারে ভেরিয়েবলের মধ্যে সংশ্লিষ্ট শেল ফাংশন নামগুলি সংজ্ঞায়িত করা হয়। শেল ফাংশন $ UN FUNCNAME [$ i] $ $ AS BASH_SOURCE [$ i] OUR ফাইলটিতে সংজ্ঞায়িত করা হয়েছে এবং $ AS BASH_SOURCE [$ i + 1]} থেকে কল করা হয়েছে}
FUNCNAME
এক্সিকিউশন কল স্ট্যাকটিতে বর্তমানে সমস্ত শেল ফাংশনের নাম সম্বলিত একটি অ্যারে ভেরিয়েবল। সূচক 0 সহ উপাদানটি বর্তমানে কার্যকর হওয়া শেল ফাংশনের নাম। নীচের দিকের সর্বাধিক উপাদান (সর্বাধিক সূচকযুক্ত একটি) "প্রধান" main এই পরিবর্তনশীল কেবল তখনই উপস্থিত থাকে যখন শেল ফাংশন কার্যকর হয় exec FUNCNAME এ নিয়োগের কোনও প্রভাব নেই এবং ত্রুটির স্থিতি ফিরে আসে return FUNCNAME যদি সেট না করা থাকে তবে এটি পরে পুনরায় সেট করা হলেও এটি তার বিশেষ বৈশিষ্ট্যগুলি হারাবে।
এই চলকটি BASH_LINENO এবং BASH_SOURCE এর সাথে ব্যবহার করা যেতে পারে। কল স্ট্যাকটি বর্ণনা করার জন্য FUNCNAME এর প্রতিটি উপাদানের BASH_LINENO এবং BASH_SOURCE এ সম্পর্কিত উপাদান রয়েছে। উদাহরণস্বরূপ, line UN BUNH_SOURCE [$ i + 1] file ফাইল থেকে $ UN FUNCNAME [$ i] called ফাইলটি কল করা হয়েছিল {AS BASH_LINENO [$ i]}} কলার অন্তর্নির্মিত এই তথ্যটি ব্যবহার করে বর্তমান কল স্ট্যাকটি প্রদর্শন করে।
[সূত্র: বাশ ম্যানুয়াল]
a
(অনুমানের a
বিষয়বস্তুগুলির echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
) উত্স হয় তবে এটি কাজ করে - তবে এটি আপনাকে a
পথ দেবে। তবে আপনি যদি এতে স্ক্রিপ্ট b
দিয়ে লিখে source a
চালনা করেন ./b
তবে তা ফিরে আসবে b
।
এই উত্তরগুলি যেগুলির বর্ণনা করেছে সেগুলির জন্য এটি সঠিক তবে আপনি যদি 'উত্স' কীওয়ার্ড ব্যবহার করে অন্য স্ক্রিপ্ট থেকে স্ক্রিপ্টটি চালান তখনও একটি সমস্যা রয়েছে (যাতে এটি একই শেলের মধ্যে চলে)। এই ক্ষেত্রে, আপনি কলিং স্ক্রিপ্টের $ 0 পাবেন। এবং এই ক্ষেত্রে, আমি মনে করি না যে স্ক্রিপ্টটির নাম নিজেই পাওয়া সম্ভব।
এটি একটি প্রান্তের মামলা এবং খুব গুরুত্ব সহকারে নেওয়া উচিত নয়। আপনি যদি অন্য স্ক্রিপ্ট থেকে সরাসরি স্ক্রিপ্টটি চালিত করেন ('উত্স' ছাড়াই), $ 0 ব্যবহার করে কাজ হবে।
যেহেতু কিছু মন্তব্য বিন্যাস ছাড়াই ফাইলের নাম সম্পর্কে জিজ্ঞাসা করেছিল, কীভাবে এটি সম্পাদন করতে হবে তার উদাহরণ এখানে রয়েছে:
FileName=${0##*/}
FileNameWithoutExtension=${FileName%.*}
উপভোগ করুন!
পুনঃ উপরে ট্যাঙ্কটালাসের (গৃহীত) উত্তর, কিছুটা পরিষ্কার উপায় ব্যবহার করা হল:
me=$(readlink --canonicalize --no-newline $0)
যদি আপনার স্ক্রিপ্টটি অন্য কোনও ব্যাশ স্ক্রিপ্ট থেকে উত্সাহিত করা হয় তবে আপনি ব্যবহার করতে পারেন:
me=$(readlink --canonicalize --no-newline $BASH_SOURCE)
আমি সম্মত হই যে এটি যদি আপনার উদ্দেশ্য ব্যবহারকারীকে প্রতিক্রিয়া জানানো হয় তবে এটি প্রত্যাখ্যানমূলক প্রতীকগুলিতে বিভ্রান্ত হবে, তবে এমন কিছু অনুষ্ঠান রয়েছে যখন আপনাকে কোনও স্ক্রিপ্ট বা অন্য ফাইলটিতে ক্যানোনিকাল নামটি পাওয়া দরকার, এবং এটিই সেরা উপায়, ইমো।
source
স্ক্রিপ্ট নামের জন্য ধন্যবাদ ।
যদি আপনার চালনার শেল স্ক্রিপ্টটি পছন্দ করে
/home/mike/runme.sh
$ 0 পুরো নাম
/home/mike/runme.sh
বেসনাম $ 0 বেস ফাইলের নামটি পাবে
runme.sh
এবং আপনার এই বুনিয়াদি নামটি একটি পরিবর্তনশীল লাইকের মধ্যে স্থাপন করা দরকার
filename=$(basename $0)
এবং আপনার অতিরিক্ত পাঠ্য যোগ করুন
echo "You are running $filename"
সুতরাং আপনার স্ক্রিপ্টগুলি পছন্দ করে
/home/mike/runme.sh
#!/bin/bash
filename=$(basename $0)
echo "You are running $filename"
this="$(dirname "$(realpath "$BASH_SOURCE")")"
এটি প্রতীকী লিঙ্কগুলি (রিয়েলপ্যাথ তা করে) সমাধান করে, স্পেসগুলি হ্যান্ডেল করে (ডাবল কোট এটি করে), এবং বর্তমান স্ক্রিপ্টের নাম সর্সযুক্ত (./myscript) বা অন্য স্ক্রিপ্টগুলি দ্বারা কল করা থাকলে ($ BASH_SOURCE এটি পরিচালনা করে) will এত কিছুর পরেও, এটি পুনরায় ব্যবহারের জন্য বা অন্য কোথাও সহজে অনুলিপি করার জন্য পরিবেশ পরিবর্তনশীলে এটি সংরক্ষণ করা ভাল (এটি =) ...
realpath
কোনও অন্তর্নির্মিত বেস কমান্ড নয়। এটি একটি স্ট্যান্ডেলোন এক্সিকিউটেবল যা কেবলমাত্র নির্দিষ্ট বিতরণে উপলব্ধ
ইন bash
আপনি ব্যবহার স্ক্রিপ্ট ফাইলের নাম পেতে পারেন $0
। সাধারণত $1
, $2
ইত্যাদি সি এল এল আর্গুমেন্ট অ্যাক্সেস করতে হয়। একইভাবে $0
স্ক্রিপ্ট (স্ক্রিপ্ট ফাইলের নাম) চালিত করে এমন নাম অ্যাক্সেস করা।
#!/bin/bash
echo "You are running $0"
...
...
আপনি যদি স্ক্রিপ্টটির মতো পথ দিয়ে থাকেন /path/to/script.sh
তবে $0
ফাইলের নামও দিয়ে দেবেন। $(basename $0)
সেক্ষেত্রে কেবল স্ক্রিপ্ট ফাইলের নাম পেতে ব্যবহার করা দরকার ।
$0
প্রশ্নের উত্তর দেয় না (যেমনটি আমি এটি বুঝতে পারি)। একটি প্রদর্শন:
$ বিড়াল স্ক্রিপ্ট.শ #! / বিন / SH প্রতিধ্বনি `বেসনাম $ 0` / ./script.sh script.sh n এলএন স্ক্রিপ্ট.শ লিংকটোস্ক্রিপ্ট / ./linktoscript linktoscript
কেউ কীভাবে ./linktoscript
মুদ্রণ পেতে পারে script.sh
?
[সম্পাদনা] উপরের মন্তব্যে প্রতি @ প্রেমেণ্ট, যদিও প্রতীকী লিঙ্ক জিনিসটি সংশ্লেষিত মনে হতে পারে, তবে এটি এমন $0
কোনও ফাইল সিস্টেম সংস্থানকে উপস্থাপন করে না এমন সাথে ঝাঁকুনি দেওয়া সম্ভব । ওপি কী চেয়েছিল তা নিয়ে কিছুটা অস্পষ্ট।
বিল হার্নান্দেজকে তথ্য ধন্যবাদ। আমি গ্রহণ করছি এমন কিছু পছন্দ যুক্ত করেছি।
#!/bin/bash
function Usage(){
echo " Usage: show_parameters [ arg1 ][ arg2 ]"
}
[[ ${#2} -eq 0 ]] && Usage || {
echo
echo "# arguments called with ----> ${@} "
echo "# \$1 -----------------------> $1 "
echo "# \$2 -----------------------> $2 "
echo "# path to me ---------------> ${0} " | sed "s/$USER/\$USER/g"
echo "# parent path --------------> ${0%/*} " | sed "s/$USER/\$USER/g"
echo "# my name ------------------> ${0##*/} "
echo
}
চিয়ার্স
সংক্ষিপ্ত, পরিষ্কার এবং সহজ, ইন my_script.sh
#!/bin/bash
running_file_name=$(basename "$0")
echo "You are running '$running_file_name' file."
আউট পুট:
./my_script.sh
You are running 'my_script.sh' file.
DIRECTORY=$(cd `dirname $0` && pwd)
আমি উপরের স্ট্যাক ওভারফ্লো প্রশ্ন থেকে উপরেরটি পেয়েছি, বাশ স্ক্রিপ্টটি বলতে পারে যে এটি কোন ডিরেক্টরিতে সঞ্চিত আছে? , তবে আমি মনে করি এটি এই বিষয়টির জন্যও কার্যকর।
দিমিত্রে রাদৌলভের উত্তরটি দ্বারা উত্সাহিত আমি যা নিয়ে এসেছি তা (যা আমি উপস্থাপিত হয়েছিল) ।
script="$BASH_SOURCE"
[ -z "$BASH_SOURCE" ] && script="$0"
echo "Called $script with $# argument(s)"
আপনি আপনার স্ক্রিপ্টকে যেভাবেই কল করবেন না কেন
. path/to/script.sh
অথবা
./path/to/script.sh
এই রকম কিছু?
export LC_ALL=en_US.UTF-8
#!/bin/bash
#!/bin/sh
#----------------------------------------------------------------------
start_trash(){
ver="htrash.sh v0.0.4"
$TRASH_DIR # url to trash $MY_USER
$TRASH_SIZE # Show Trash Folder Size
echo "Would you like to empty Trash [y/n]?"
read ans
if [ $ans = y -o $ans = Y -o $ans = yes -o $ans = Yes -o $ans = YES ]
then
echo "'yes'"
cd $TRASH_DIR && $EMPTY_TRASH
fi
if [ $ans = n -o $ans = N -o $ans = no -o $ans = No -o $ans = NO ]
then
echo "'no'"
fi
return $TRUE
}
#-----------------------------------------------------------------------
start_help(){
echo "HELP COMMANDS-----------------------------"
echo "htest www open a homepage "
echo "htest trash empty trash "
return $TRUE
} #end Help
#-----------------------------------------------#
homepage=""
return $TRUE
} #end cpdebtemp
# -Case start
# if no command line arg given
# set val to Unknown
if [ -z $1 ]
then
val="*** Unknown ***"
elif [ -n $1 ]
then
# otherwise make first arg as val
val=$1
fi
# use case statement to make decision for rental
case $val in
"trash") start_trash ;;
"help") start_help ;;
"www") firefox $homepage ;;
*) echo "Sorry, I can not get a $val for you!";;
esac
# Case stop