मैं एक बैश स्क्रिप्ट में स्क्रिप्ट फ़ाइल नाम को कैसे जान सकता हूँ?


605

मैं स्क्रिप्ट के अंदर बैश स्क्रिप्ट फ़ाइल का नाम कैसे निर्धारित कर सकता हूं?

जैसे अगर मेरी स्क्रिप्ट फाइल में है runme.sh, तो मैं इसे हार्डकॉपी किए बिना "आप रनमे.श" संदेश प्रदर्शित करने के लिए कैसे बनाऊंगा?


3
[? सकते हैं एक bash स्क्रिप्ट बताओ क्या निर्देशिका में अपने संग्रहीत] इसी प्रकार के (करने के लिए stackoverflow.com/questions/59895/... )
Rodrigue

जवाबों:


630
me=`basename "$0"`

सिम्कलिन 1 के माध्यम से पढ़ने के लिए , जो आमतौर पर आप नहीं चाहते हैं (आप आमतौर पर इस तरह से उपयोगकर्ता को भ्रमित नहीं करना चाहते हैं), कोशिश करें:

me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"

IMO, यह भ्रामक आउटपुट उत्पन्न करेगा। "मैं foo.sh भाग गया, लेकिन यह कह रहा हूँ कि मैं bar.sh चला रहा हूँ !? एक बग होना चाहिए!" इसके अलावा, अलग-अलग नाम वाले सीमलिंक होने के उद्देश्यों में से एक नाम के आधार पर अलग-अलग कार्यक्षमता प्रदान करना है (जैसा कि कुछ प्लेटफार्मों पर gzip और gunzip लगता है)।


1 यही है कि सीमलिंक को हल करने के लिए जब उपयोगकर्ता निष्पादित करता है foo.shजो वास्तव में एक सिमलिंक है bar.sh, तो आप bar.shइसके बजाय हल किए गए का उपयोग करना चाहते हैं foo.sh


40
$ 0 आपको वह नाम देता है जिसके माध्यम से स्क्रिप्ट को लागू किया गया था, न कि वास्तविक स्क्रिप्ट फ़ाइल का वास्तविक पथ।
क्रिस कॉनवे

4
यह तब तक काम करता है जब तक कि आपको सिमलिंक के माध्यम से नहीं बुलाया जा रहा हो। लेकिन, फिर भी, यह आम तौर पर आप वैसे भी क्या चाहते हैं, आईएमई।
टंकटालस

78
उन लिपियों के लिए काम नहीं करता है जो कि आह्वान के विपरीत खट्टी हैं।
चार्ल्स डफी


8
-1, 1. रीडलिंक केवल एक सिम्क्लिन गहरी यात्रा करेगा, 2. $0पहले उदाहरण में शब्द बंटवारे के अधीन है, 3. $0बेसनेम, रीडिंकल और इको में पारित किया जाता है, जो इसे एक कमांड लाइन स्विच के रूप में माना जाता है। । मैं me=$(basename -- "$0")पठनीयता की कीमत पर इसके बजाय या बहुत अधिक कुशलता से सुझाव देता हूं me=${0##*/}। सिम्बलिंक के लिए, me=$(basename -- "$(readlink -f -- "$0")")ग्नू बर्तन को ग्रहण करना, अन्यथा यह एक बहुत लंबी स्क्रिप्ट होगी जिसे मैं यहाँ नहीं लिखूंगा।
स्कोर_उंडर

246
# ------------- SCRIPT ------------- #


#!/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

# ------------- बुलाया ------------- ## ------------- बुलाया ------------- #

# अगली पंक्ति पर ध्यान दें, पहला तर्क डबल के भीतर कहा जाता है, # अगली पंक्ति पर ध्यान दें, पहला तर्क डबल के भीतर कहा जाता है, 
# और एकल उद्धरण, क्योंकि इसमें दो शब्द हैं# और एकल उद्धरण, क्योंकि इसमें दो शब्द हैं

$ /misc/shell_scripts/check_root/show_parms.sh "'हैलो वहाँ" "" विलियम "/ misc / shell_scripts / check_root / show_parms "" हैलो वहाँ " " "विलियम" 

# ------------- परिणाम ------------- ## ------------- परिणाम ------------- #

# तर्क के साथ ---> 'नमस्ते वहाँ' 'विलियम'# तर्क के साथ ---> 'नमस्ते वहाँ' 'विलियम'
# $ 1 ----------------------> 'नमस्ते वहाँ'# $ 1 ----------------------> 'नमस्ते वहाँ'
# $ 2 ----------------------> 'विलियम'# $ 2 ----------------------> 'विलियम'
# मेरे लिए रास्ता --------------> /misc/shell_scripts/check_root/show_parms.sh# मेरे लिए रास्ता --------------> /misc/shell_scripts/check_root/show_parms.sh
# मूल पथ -------------> / misc / shell_scripts / check_root# मूल पथ -------------> / misc / shell_scripts / check_root
# मेरा नाम -----------------> show_parms.sh# मेरा नाम -----------------> show_parms.sh

# ------------- समाप्त ------------- ## ------------- समाप्त ------------- #

11
@NickC को हटाना
cychoi

1
मैं show_paramsबिना किसी वैकल्पिक विस्तार के बस नाम कैसे प्राप्त कर सकता हूं ?
एक्यूमेनस

स्क्रिप्ट के दूसरे फ़ोल्डर से मंगाने पर काम नहीं करने पर। पथ में शामिल है ${0##*/}। GitBash का उपयोग करके परीक्षण किया गया।
एलिकएल्ज़िन-किलाका

1
उपर्युक्त ने मेरे लिए एक .bash_login स्क्रिप्ट से काम नहीं किया, लेकिन $ BASH_SOURCE का दिमित्रे रादोलोव समाधान शानदार काम करता है।
जॉन

@ जॉन निश्चित रूप से आपका मतलब है .bash_profile ? या वैकल्पिक रूप से .bashrc ? हालांकि आपको पता होना चाहिए कि वहाँ कुछ सूक्ष्म अंतर हैं कि वे कैसे आह्वान / खट्टा हैं। मैं थका हुआ हूं, लेकिन अगर मैं सही सोच रहा हूं, तो समस्या की संभावना होगी। एक जगह यह मायने रखती है कि क्या आप किसी सिस्टम में दूरस्थ रूप से ssh बनाम स्थानीय सिस्टम में लॉग इन कर रहे हैं।
प्रिएफ्टन

193

बैश के साथ > = 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"

24
महान! इसका उत्तर जो दोनों के लिए काम करता है ।/scrip.sh और स्रोत
।/cript.sh

4
यह वही है जो मैं चाहता हूं, और dirname $BASE_SOURCEनिर्देशिकाओं को प्राप्त करने के लिए आसानी से " " का उपयोग करना है जो स्क्रिप्ट स्थित हैं।
लैरी कै

2
स्व-हटाने वाली स्क्रिप्ट लिखते समय मैंने उस अंतर को लगभग कठिन तरीके से सीखा। सौभाग्य से 'rm' को 'rm -i' :) कहा गया
kervin

वैसे भी। नाम पाने के लिए। मैंने पाया है कि $ 1 हमेशा के लिए सेट नहीं है ।/s ...
डेविड मोकोन बॉन्ड

1
यह BASH_SOURCE में है , है ना?
दिमित्रे रादोलोव

69

$BASH_SOURCE स्क्रिप्ट सोर्स करते समय सही उत्तर देता है।

हालाँकि, इसमें स्क्रिप्ट नाम फ़ाइल करने के लिए केवल पथ का उपयोग करना शामिल है:

$(basename $BASH_SOURCE) 

2
यह उत्तर IMHO सबसे अच्छा है क्योंकि ते समाधान स्वयं-दस्तावेज़ीकरण कोड का उपयोग करता है। $ BASH_SOURCE किसी भी दस्तावेज़ को पढ़े बिना पूरी तरह से समझ में आता है, जैसे $ {0 ## * /} नहीं है
एंड्रियास एम। ओबेरहेम

यह उत्तर अधिक मूल्य का है क्योंकि मेरा मानना ​​है कि अगर हम जैसे चाहें . <filename> [arguments], $0कॉल करने वाले का नाम बता देंगे। कम से कम OSX पर सुनिश्चित करने के लिए।
मिहिर

68

स्क्रिप्ट नाम उस में रिक्त स्थान है, तो एक और अधिक मजबूत तरीके से उपयोग करने के लिए है "$0"या "$(basename "$0")"- या MacOS पर: "$(basename \"$0\")"। यह किसी भी तरह से नाम को आम होने या व्याख्या करने से रोकता है। सामान्य तौर पर, शेल में चर नामों को हमेशा डबल करना अच्छा होता है।


2
प्रत्यक्ष उत्तर + संक्षिप्त के लिए +1। अगर मुझे सिम्लिंक सुविधाओं की आवश्यकता है तो मैं सुझाव देता हूं: ट्रैविस बी हार्टवेल का जवाब।
ट्रेवर बोयड स्मिथ

26

यदि आप इसे बिना रास्ते के चाहते हैं तो आप उपयोग करेंगे ${0##*/}


और क्या होगा अगर मैं इसे बिना किसी वैकल्पिक फ़ाइल एक्सटेंशन के चाहता हूं?
एक्यूमेनस

किसी एक्सटेंशन को हटाने के लिए, आप "$ {VARIABLE% .ext}" आज़मा सकते हैं, जहाँ VARIABLE वह मान है जो आपको $ {0 ## * /} से मिला है और ".ext" वह एक्सटेंशन है जिसे आप निकालना चाहते हैं।
ब्रायन वी।

19

लिनक्स पर क्रिस कॉनवे का जवाब देने के लिए (कम से कम) आप ऐसा करेंगे:

echo $(basename $(readlink -nf $0))

readlink एक प्रतीकात्मक लिंक के मूल्य को प्रिंट करता है। यदि यह एक प्रतीकात्मक लिंक नहीं है, तो यह फ़ाइल नाम को प्रिंट करता है। -नई से कहता है कि नई लाइन न छापें। -यदि यह पूरी तरह से लिंक का पालन करने के लिए कहता है (यदि एक प्रतीकात्मक लिंक किसी अन्य लिंक का लिंक होता है, तो यह उस एक को भी हल करेगा)।


2
-n हानिरहित है लेकिन आवश्यक नहीं है क्योंकि $ (...) संरचना इसे ट्रिम कर देगी।
झोराफुई

16

मैंने इस लाइन को हमेशा काम करने के लिए पाया है, भले ही फ़ाइल को स्क्रिप्ट के रूप में सॉर्ट किया जा रहा हो या चलाया जा रहा हो।

echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"

यदि आप readlinkअपने ऊपर मिलने वाले पथ पर, पुनरावर्ती या गैर-पुनरावर्ती रूप से उपयोग किए जाने वाले सिमिलिंक का अनुसरण करना चाहते हैं ।

एक-लाइनर कार्यों का कारण BASH_SOURCEपर्यावरण चर और इसके सहयोगी के उपयोग द्वारा समझाया गया है FUNCNAME

BASH_SOURCE

एक सरणी चर जिसका सदस्य स्रोत फ़ाइल नाम हैं, जहां FUNCNAME सरणी चर में संबंधित शेल फ़ंक्शन नाम परिभाषित किए गए हैं। शेल फ़ंक्शन $ {FUNCNAME [$ i]} को $ {BASH_SOURCE [$ i]} में परिभाषित किया गया है और $ {BASH_SOURCE [$ i + 1]} से बुलाया गया है।

FUNCNAME

एक शेल वैरिएबल जिसमें सभी शेल फ़ंक्शंस के नाम हैं जो वर्तमान में निष्पादन कॉल स्टैक में हैं। इंडेक्स 0 वाला तत्व किसी भी वर्तमान में निष्पादित शेल फ़ंक्शन का नाम है। सबसे नीचे का तत्व (उच्चतम सूचकांक वाला) "मुख्य" है। यह चर केवल तब होता है जब शेल फ़ंक्शन निष्पादित हो रहा हो। FUNCNAME को असाइनमेंट का कोई प्रभाव नहीं है और एक त्रुटि स्थिति लौटाता है। यदि FUNCNAME परेशान है, तो यह अपने विशेष गुणों को खो देता है, भले ही यह बाद में रीसेट हो।

इस चर का उपयोग BASH_LINENO और BASH_SOURCE के साथ किया जा सकता है। FUNCNAME के ​​प्रत्येक तत्व में कॉल स्टैक का वर्णन करने के लिए BASH_LINENO और BASH_SOURCE में संबंधित तत्व हैं। उदाहरण के लिए, $ {FUNCNAME [$ i]} को फ़ाइल से $ {BASH_SOURCE [$ i + 1]} लाइन नंबर $ {BASH_LINENO [$ i]} पर कॉल किया गया था। इस जानकारी का उपयोग कर कॉल करने वाला बिलियन वर्तमान कॉल स्टैक को प्रदर्शित करता है।

[स्रोत: बैश मैनुअल]


2
यह काम करता है यदि आप एक इंटरैक्टिव सत्र से फ़ाइल में स्रोत a (मान लें कि aसामग्री है echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}") - तो यह आपको aरास्ता देगा। लेकिन अगर आप इसके bसाथ एक स्क्रिप्ट लिखते हैं source aऔर चलाते हैं ./b, तो यह वापस आ जाएगी b
पीएसकोकिक

12

ये उत्तर उन मामलों के लिए सही हैं जो वे कहते हैं, लेकिन एक समस्या अभी भी है यदि आप 'स्रोत' कीवर्ड का उपयोग करके किसी अन्य स्क्रिप्ट से स्क्रिप्ट चलाते हैं (ताकि यह उसी शेल में चलता है)। इस स्थिति में, आपको कॉलिंग स्क्रिप्ट का $ 0 मिलता है। और इस मामले में, मुझे नहीं लगता कि स्क्रिप्ट का नाम ही संभव है।

यह एक एज केस है और इसे टीओओ को गंभीरता से नहीं लेना चाहिए। यदि आप स्क्रिप्ट को दूसरी स्क्रिप्ट से सीधे ('स्रोत' के बिना) चलाते हैं, तो $ 0 का उपयोग करना काम करेगा।


2
आपके पास एक बहुत अच्छी बात है। एज केस नहीं IMO। हालांकि इसका एक समाधान है: ऊपर देखें दिमित्रे रादलोव का जवाब
सर्ज वूटियर

10

चूंकि कुछ टिप्पणियों ने विस्तार के बिना फ़ाइल नाम के बारे में पूछा, यहां एक उदाहरण दिया गया है कि इसे कैसे पूरा किया जाए:

FileName=${0##*/}
FileNameWithoutExtension=${FileName%.*}

का आनंद लें!


9

पुन: टंकटालस (स्वीकृत) से ऊपर का उत्तर, थोड़ा साफ करने का तरीका उपयोग करना है:

me=$(readlink --canonicalize --no-newline $0)

यदि आपकी स्क्रिप्ट को किसी अन्य बैश स्क्रिप्ट से अलग कर दिया गया है, तो आप इसका उपयोग कर सकते हैं:

me=$(readlink --canonicalize --no-newline $BASH_SOURCE)

मैं मानता हूं कि अगर आपके उद्देश्य उपयोगकर्ता को प्रतिक्रिया प्रदान करना है, तो यह आपके लिए सहानुभूति को भ्रमित करने वाला होगा, लेकिन ऐसे मौके भी आते हैं जब आपको किसी स्क्रिप्ट या अन्य फ़ाइल में विहित नाम प्राप्त करने की आवश्यकता होती है, और यह सबसे अच्छा तरीका है, imo।


1
sourceD स्क्रिप्ट नामों के लिए धन्यवाद ।
फ्रेड्रिक गॉस

8

आप अपने स्क्रिप्ट नाम (पूर्ण पथ के साथ) का निर्धारण करने के लिए $ 0 का उपयोग कर सकते हैं - केवल स्क्रिप्ट नाम प्राप्त करने के लिए आप उस चर को ट्रिम कर सकते हैं

basename $0

8

अगर आपका आह्वान शेल स्क्रिप्ट की तरह है

/home/mike/runme.sh

$ 0 पूरा नाम है

 /home/mike/runme.sh

basename $ 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"

7
this="$(dirname "$(realpath "$BASH_SOURCE")")"

यह प्रतीकात्मक लिंक (realpath ऐसा करता है) को हल करता है, रिक्त स्थान को संभालता है (दोहरा उद्धरण ऐसा करता है), और खट्टा होने पर भी वर्तमान स्क्रिप्ट का नाम खोजेगा (./myscript) या अन्य लिपियों द्वारा बुलाया ($ BASH_SOURCE हैंडल)। आखिरकार, इसे पर्यावरण के चर में फिर से उपयोग करने के लिए या आसान कॉपी के लिए कहीं और सहेजना अच्छा है (यह =) ...


3
FYI realpathकरना बिल्ट-इन BASH कमांड नहीं है। यह एक स्टैंडअलोन निष्पादन योग्य है जो केवल कुछ वितरणों में उपलब्ध है
StvanW

4

में bashआप का उपयोग कर स्क्रिप्ट फ़ाइल नाम प्राप्त कर सकते हैं $0। आम तौर पर $1, $2आदि सीएलआई तर्कों का उपयोग करते हैं। इसी तरह $0उस नाम को एक्सेस करना है जो स्क्रिप्ट (स्क्रिप्ट फ़ाइल नाम) को ट्रिगर करता है।

#!/bin/bash
echo "You are running $0"
...
...

यदि आप स्क्रिप्ट को पथ के साथ लागू करते हैं, /path/to/script.shतो $0पथ के साथ फ़ाइल नाम भी देंगे। उस मामले में $(basename $0)केवल स्क्रिप्ट फ़ाइल नाम प्राप्त करने के लिए उपयोग करने की आवश्यकता है ।


3
echo "$(basename "`test -L ${BASH_SOURCE[0]} \
                   && readlink ${BASH_SOURCE[0]} \
                   || echo ${BASH_SOURCE[0]}`")"

2

$0सवाल का जवाब नहीं देता (जैसा कि मैं इसे समझता हूं)। प्रदर्शन:

$ बिल्ली लिपि
#! / Bin / श
गूंज `बेसन $ 0`
$ ./script.sh 
script.sh
$ ln script.sh लिंकटोसस्क्रिप्ट
$ ./linktoscript 
linktoscript

किसी ./linktoscriptको प्रिंट आउट कैसे मिलता है script.sh?

[EDIT] प्रति टिप्पणी में @ephemient के ऊपर, हालांकि प्रतीकात्मक लिंक चीज़ से विवाद हो सकता है, $0इस तरह से फ़ेल्ड करना संभव है कि यह एक फ़ाइल सिस्टम संसाधन का प्रतिनिधित्व नहीं करता है। ओपी थोड़ा अस्पष्ट है कि वह क्या चाहता है।


ऊपर दिए गए मेरे उत्तर के लिए इसका उत्तर जोड़ा गया है, लेकिन मैं असहमत हूं कि यह वही है जो वास्तव में चाहता था (या कि आप इसे चाहते हैं, कुछ मौजूदा परिस्थितियों को छोड़कर जो मैं अभी थाह नहीं कर सकता हूं)
टैंकल्टस

2
मुझे लगता है कि script.sh के बजाय लिंकटोसस्क्रिप्ट को प्रिंट करना एक विशेषता है, बग नहीं। कई यूनिक्स कमांड उनके व्यवहार को बदलने के लिए उनके नाम का उपयोग करते हैं। एक उदाहरण vi / ex / view है।
माउविसील

@ टंकटालस: ऐसे मामले हैं जहां आप फ़ाइल के वास्तविक स्थान के आधार पर व्यवहार को बदलना चाहते हैं - पिछली परियोजना पर मेरे पास "सक्रिय शाखा" स्क्रिप्ट थी, जो उस शाखा से कई साधनों को पथ में सम्‍मिलित करेगी जो मैं था काम पर; वे उपकरण तब पता लगा सकते हैं कि उन्हें सही फ़ाइलों के विरुद्ध चलाने के लिए किस निर्देशिका में जाँच की गई थी।
एंड्रयू आइलेट

2

बिल हर्नांडेज़ को जानकारी धन्यवाद। मैंने कुछ प्राथमिकताएँ जोड़ीं, जिन्हें मैं अपना रहा हूँ।

#!/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
}

चियर्स


1

लघु, स्पष्ट और सरल, में 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.

0
DIRECTORY=$(cd `dirname $0` && pwd)

मुझे एक और स्टैक ओवरफ्लो प्रश्न से ऊपर मिला, क्या एक बैश स्क्रिप्ट बता सकती है कि यह किस निर्देशिका में संग्रहीत है? , लेकिन मुझे लगता है कि यह इस विषय के लिए भी उपयोगी है।


0

यहाँ मैं दिमित्रे रादोलोव के उत्तर से प्रेरित होकर आया हूं (जो कि मैंने उतारा है, वैसे)

script="$BASH_SOURCE"
[ -z "$BASH_SOURCE" ] && script="$0"

echo "Called $script with $# argument(s)"

आपके स्क्रिप्ट को कॉल करने के तरीके की परवाह किए बिना

. path/to/script.sh

या

./path/to/script.sh


-6

कुछ इस तरह से?

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

5
-1, प्रश्न का उत्तर नहीं देता (स्क्रिप्ट के नाम को खोजने का तरीका नहीं दिखाता), और एक बहुत ही छोटी-सी स्क्रिप्ट में एक भ्रामक उदाहरण है।
स्कोर_उंडर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.