বাশে নূরের ব্যবহারের ক্ষেত্রে কী?


123

আমি বাশ (:) এ নূপুর অনুসন্ধান করেছি, তবে কোনও ভাল তথ্য খুঁজে পেলাম না। এই অপারেটরের সঠিক উদ্দেশ্য বা ব্যবহারের ক্ষেত্রে কী?

আমি অনুসরণ করার চেষ্টা করেছি এবং এটি আমার জন্য এটির মতো কাজ করছে:

[mandy@root]$ a=11
[mandy@root]$ b=20
[mandy@root]$ c=30
[mandy@root]$ echo $a; : echo $b ; echo $c
10
30

দয়া করে আমাকে জানান, এই অপারেটরটির যে কোনও ব্যবহারের ক্ষেত্রে রিয়েল টাইম বা যে কোনও জায়গায় এটি ব্যবহার করা বাধ্যতামূলক।


করার জন্য একটি চেহারা আছে stackoverflow.com/questions/7444504/...
স্টিফেন Rouberol

নোট করুন যে :বিল্ট-ইন বোর্ন শেল এবং ksh পাশাপাশি বাশের মধ্যে বিদ্যমান।
ঘোটি

আরও দেখুন :মধ্যে tldp.org/LDP/abs/html/special-chars.html
choroba

6
এটি কীভাবে আসল প্রশ্ন নয়? আমি মনে করি এটি সত্যিই একটি ভাল প্রশ্ন। এমনকি আমি এটির জন্য ভাল ব্যবহার করি তবে আমি কোনও উত্তর পোস্ট করতে পারি না।
স্টিভেন লু

উত্তর:


175

এটি historicalতিহাসিক কারণে আরও আছে। কোলন builtin :ঠিক সমতূল্য truetrueরিটার্নের মানটি গুরুত্বপূর্ণ হলে এটি ব্যবহার করা প্রচলিত , উদাহরণস্বরূপ অসীম লুপে:

while true; do
  echo 'Going on forever'
done

:শেল সিনট্যাক্সের একটি কমান্ডের প্রয়োজন হলে এটি ব্যবহার করা প্রচলিত তবে আপনার কিছুই করার নেই।

while keep_waiting; do
  : # busy-wait
done

:Builtin তারিখ সব পথ ফিরে থম্পসন শেল , এটি ছিল বর্তমান মধ্যে ইউনিক্স V6:থম্পসন শেলের gotoবিবৃতিটির জন্য একটি লেবেল সূচক ছিল । লেবেলটি কোনও পাঠ্য হতে পারে, সুতরাং :কোনও মন্তব্য সূচক হিসাবে দ্বিগুণ হয়ে গেছে (যদি নেই goto comment, তবে : commentকার্যকরভাবে একটি মন্তব্য করা হবে)। বোর্ন শেল ছিল না gotoকিন্তু রাখা :

একটি সাধারণ বাগ্ধারা যে ব্যবহারসমূহ :হয় : ${var=VALUE}, যা সেট varথেকে VALUEযদি এটি সেট না ছিল আর যদি কিছুই না varইতিমধ্যে সেট করা হয়েছে। এই কনস্ট্রাক্টটি কেবলমাত্র একটি পরিবর্তনশীল প্রতিস্থাপনের আকারে বিদ্যমান এবং এই পরিবর্তনশীল প্রতিস্থাপনটি কোনওভাবে কমান্ডের অংশ হওয়া দরকার: কোনও অপ-কমান্ড দুর্দান্তভাবে কাজ করে।

আরও দেখুন কোলন বিল্টিন কী উদ্দেশ্যে কাজ করে?


11
ভাল সংক্ষিপ্তসার। এছাড়াও, মূল বোর্ন শেল #মন্তব্যগুলির জন্য ব্যবহার করেনি (বা #!/bin/shশেবাং); :কমান্ড চালু মন্তব্য, এবং সাদাসিধা প্রোগ্রামার যারা তাদের মন্তব্য তারার একটি চমৎকার বক্স তৈরি ঘটা দুর্ভোগ: : ****(অথবা, তার থেকেও খারাপ, : * * *)।
জোনাথন লেফলার

3
@ জোনাথনলফলার: আমাকে লজ্জা দিলেও আমি তা পাই না। কি হবে : * * *?
দেবসোলার

7
যেহেতু :একটি কমান্ড, শেলটি এখনও এটিকে :উপেক্ষা করে তা আবিষ্কার করার আগে তার তর্কগুলি প্রক্রিয়া করতে হবে । বেশিরভাগ ক্ষেত্রে, আপনি কেবল *বর্তমান ডিরেক্টরিতে ফাইলের তালিকায় প্রসারিত করতে শেলটিকে অতিরিক্ত কাজ করে যাচ্ছেন ; এটি আসলে স্ক্রিপ্টটি কীভাবে কাজ করে তা প্রভাবিত করবে না।
চ্যানার

আমি মনে করি এটি আপনার স্ক্রিপ্টটি ব্যর্থ করে দিতে পারে যদি আপনি প্রচুর ফাইলের সাহায্যে কোনও ডিরেক্টরিতে চালিত হন, গ্লোব সম্প্রসারণ কমান্ডের দৈর্ঘ্যের সীমা ছাড়িয়ে যায়? আপনি যদি শুধুমাত্র set -eচালু আছে। যাইহোক, আশা করি আমরা সকলেই কেবল ব্যবহার করতে সম্মত হতে পারি #:)
জ্যাক ও'কনর

2
আমি while : ; do ... ; doneদ্রুত এবং নোংরা অসীম লুপ চাইলে আমি মাঝে মাঝে ব্যবহার করি। (সাধারণত sleepলুপটিতে একটি থাকে এবং আমি এটি মারতে Ctrl-C টাইপ করি))
কিথ থম্পসন

21

আমি সমস্ত কোডের বাইরে মন্তব্য করার সময় যদি স্টেটমেন্টগুলির জন্য এটি ব্যবহার করি। উদাহরণস্বরূপ আপনার একটি পরীক্ষা আছে:

if [ "$foo" != "1" ]
then
    echo Success
fi

তবে আপনি এর মধ্যে থাকা সমস্ত কিছু অস্থায়ীভাবে মন্তব্য করতে চান:

if [ "$foo" != "1" ]
then
    #echo Success
fi

যা বাশকে সিন্ট্যাক্স ত্রুটি দেয়:

line 4: syntax error near unexpected token `fi'
line 4: `fi'

বাশের খালি ব্লক (ডাব্লুটিএফ) থাকতে পারে না। সুতরাং আপনি একটি অপশন যুক্ত করুন:

if [ "$foo" != "1" ]
then
    #echo Success
    :
fi

অথবা আপনি লাইনগুলি মন্তব্য করার জন্য কোনও অপশন ব্যবহার করতে পারেন:

if [ "$foo" != "1" ]
then
    : echo Success
fi

12

যদি আপনি এটি ব্যবহার করেন set- eতবে কোনও ব্যর্থতা দেখা দিলে স্ক্রিপ্ট থেকে বেরিয়ে না আসার || :একটি দুর্দান্ত উপায় (এটি স্পষ্টতই এটি পাস করে দেয়)।


1
আমি নির্দিষ্ট শেল-স্ক্রিপ্ট-কলিং অ্যাপ্লিকেশনগুলির জন্য এটি দরকারী পেয়েছি। উদাহরণস্বরূপ, ম্যাকের অটোমেটার ত্রুটি থেকে প্রস্থান করবে এবং কেন তা আপনাকে জানাবে না। তবে || :এরপরে ব্যবহার করে ত্রুটিটি নিজেই একটি দিয়ে নিজেকে পরিচালনা করা exit 0আপনাকে ডিবাগিংয়ের সময় অ্যাপ্লিকেশন উইন্ডোতে সমস্ত স্টডআউট এবং স্টার্ডার প্রদর্শন করতে দেয়। { foo ... 2>&1; } || :আরও জটিল ট্র্যাপ স্থাপন এবং যদি-তারপর হয় তার চেয়ে কোনটি সহজ তা বিবেচনা করুন ।
বিজোর

7

আপনি :একটি কমান্ড সরবরাহ করতে ব্যবহার করবেন যা সফল হয় তবে কিছুই করে না। এই উদাহরণে "ভার্বোসিটি" কমান্ডটি সেট করে ডিফল্টরূপে বন্ধ করা হয় :। 'V' বিকল্পটি এটি চালু করে।

#!/bin/sh
# example
verbosity=:                         
while getopts v OPT ; do          
   case $OPT in                  
       v)        
           verbosity=/bin/realpath 
       ;;
       *)
           exit "Cancelled"
       ;;             
   esac                          
done                              

# `$verbosity` always succeeds by default, but does nothing.                              
for i in * ; do                   
  echo $i $($verbosity $i)         
done                              

$ example
   file

$ example -v
   file /home/me/file  

কঠোরভাবে বলতে গেলে, একটি ভেরিয়েবলকে একটি মান নির্ধারণ করা "কিছু করা", সুতরাং এটি কেন আপনার কেস স্টেটমেন্টটিতে ত্রুটি ফেলবে না।
কডেনিনজা

@ কোডেনিনজা: কেউ দাবি করেনি যে ভেরিয়েবল অ্যাসাইনমেন্ট "কিছুই করেনি"; $(verbosity $i)মুল বক্তব্যটি হ'ল পরবর্তী (এবং শর্তাধীন) কিছুই করে না।
অরবিটে হালকা ঘোড়দৌড়

6

aliasযুক্তি উপেক্ষা করুন

কিছু সময় আপনি এমন একটি উপাধি রাখতে চান যা কোনও যুক্তি গ্রহণ করে না। আপনি এটি ব্যবহার করে এটি করতে পারেন ::

> alias alert_with_args='echo hello there'

> alias alert='echo hello there;:'

> alert_with_args blabla
hello there blabla

> alert blabla
hello there

ডাউনভোটার নয় :, দুর্ভাগ্যক্রমে এই উত্তরটি কীভাবে কাজ করে তা প্রমাণ করে না। আপনি যে উদাহরণ সরবরাহ করেছেন তা অপ্রয়োজনীয় বলে মনে হচ্ছে।
কডেনিনজা

2
প্রশ্নটি এটি কীভাবে কাজ করে তা নয়, তবে ব্যবহারের ক্ষেত্রে কী রয়েছে । এটি সত্য যে আমার উত্তরটি স্ট্যাকওভারফ্লো . com/ a/ 37170755/6320039 এর সাথে কিছুটা মিল । তবে এটি সত্যিই একই ব্যবহারের ক্ষেত্রে নয়। আমি আমার উত্তরটি উন্নত করতে পেরে খুশি হব তবে কীভাবে এখানে আছি তা আমি জানি না ..
ইউলিস বিএন

1
এটি কিছুটা মজাদার- এক কোণার ক্ষেত্রে, যদি আপনি চান- তবে এখনও বেশ আকর্ষণীয় এবং কারও পিছনের পকেটে থাকা একটি চালাক কৌশল হতে পারে।
মাইক এস


2
@ জোয়েহিউল যেহেতু এলিয়াসগুলি কোনও ধরণের মৃত্যুদন্ডের পূর্বে পাঠ্যগতভাবে প্রতিস্থাপন করা হয় , #একই উপাখ্যানটি একই পংক্তির পরে সিন্থেটিকভাবে আসা সমস্ত কিছুকে উপেক্ষা করার জন্য একটি উপকরণ ব্যবহার করে । এটি সত্যিই আলাদা (বিবেচনা করুন my_alias arg ; other_commandবা, বিপরীতে, my_alias arg1 {BACKSLASH}{NEWLINE} arg2), এবং সম্ভবত আপনি যা চান তা এটি সিনট্যাক্স ত্রুটির কারণ হতে পারে (অনুমান করুন while my_alias ; do true ; doneবা কী while true ; do my_alias ; doneকরবে)।
মাওলান

4

একটি ব্যবহার হ'ল মাল্টলাইন মন্তব্য, বা আপনার কোডের অংশটি এখানে ফাইলের সাথে একত্রে ব্যবহার করে পরীক্ষা করার উদ্দেশ্যে মন্তব্য করা।

: << 'EOF'

This part of the script is a commented out

EOF

চারপাশে উদ্ধৃতি ব্যবহার করতে ভুলবেন না EOFযাতে যাতে কোনও অভ্যন্তরের কোড মূল্যায়ন না করে $(foo)। এছাড়া মতো স্বজ্ঞাত টারমিনেটর নাম ব্যবহার করে মূল্য হতে পারে NOTES, SCRATCHPADঅথবা TODO


কুল কৌশল! বিশেষত স্ক্র্যাচ নোট এবং কোডের জন্য যখন হার্ড-মোড়ক থাকে তখন কয়েক "#" গুলি প্রয়োজন। একটি পার্শ্ব প্রতিক্রিয়া হ'ল মন্তব্য লাইনের বিপরীতে কিছু সিনট্যাক্স হাইলাইটার হেরিডোকগুলিকে অগ্রাহ্য করবে এবং এগুলি স্বাভাবিক কোডের (বা কমপক্ষে সরল পাঠ্য) মতো রঙ করবে। মন্তব্য-আউট কোড পরীক্ষা করার জন্য, বা একটি নিওন মন্তব্য রঙে অনুচ্ছেদ থেকে আপনার চোখ সংরক্ষণ করার জন্য যা দুর্দান্ত হতে পারে। কেবলমাত্র সতর্কতাই হ'ল এই জাতীয় ব্লকগুলি ভাগ করা কোডের মন্তব্য হিসাবে চিহ্নিত করা উচিত, যেহেতু বাক্য গঠনটি অনন্য এবং বিভ্রান্তির কারণ হতে পারে। তারপরে আবার, এটি শেল যা আমরা বলছি, যেখানে বিভ্রান্তির সম্ভাবনা সিস্টেমিক।
বিঘোর 21

3

আমার দুটি।

এমডোড POD মন্তব্য

এর বেশ মজাদার অ্যাপ্লিকেশন :হ'ল ব্যাশ স্ক্রিপ্টগুলিতে POD মন্তব্য এম্বেড করার জন্য , যাতে ম্যান পেজগুলি দ্রুত তৈরি করা যায়। অবশ্যই, একশেষে পার্ল ;-) পুরো স্ক্রিপ্টটি আবার লিখতে হবে;

রান-টাইম ফাংশন বাঁধাই

রান-টাইমে বাঁধার কাজগুলির জন্য এটি এক ধরণের কোড প্যাটার্ন। ফাই, একটি নির্দিষ্ট পতাকা সেট করা থাকলে কেবল কিছু করার জন্য একটি ডিবাগিং ফাংশন রয়েছে:

#!/bin/bash
# noop-demo.sh 
shopt -s expand_aliases

dbg=${DBG:-''}

function _log_dbg {
    echo >&2 "[DBG] $@"
}

log_dbg_hook=':'

[ "$dbg" ] && log_dbg_hook='_log_dbg'

alias log_dbg=$log_dbg_hook


echo "Testing noop alias..."
log_dbg 'foo' 'bar'

তুমি পাও:

$ ./noop-demo.sh 
Testing noop alias...
$ DBG=1 ./noop-demo.sh 
Testing noop alias...
[DBG] foo bar

2

কখনও কখনও কোনও অপ-ক্লজ আপনার কোডটি আরও পঠনযোগ্য করে তুলতে পারে।

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

function chgpath() {
    # toC, fromC are the first characters of the argument paths.
    if [[ "$toC" == / && "$fromC" == / ]] || [[ "$toC" != / && "$fromC" != / ]]
    then
        true      # continue with function
    else
        return 1  # Skip function.
    fi

কিছু বিকাশকারী অপ-অপসারণ করতে চাইবে তবে এর অর্থ শর্তযুক্ত অবহেলা করা হবে:

function chgpath() {
    # toC, fromC are the first characters of the argument paths.
    if [[ "$toC" != / || "$fromC" == / ]] && [[ "$toC" == / || "$fromC" != / ]]
    then
        return 1  # Skip function.
    fi

এখন -আর আমার মতে- যদি আপনি যে ফাংশনটি সম্পাদন করতে চান তা যদি শর্তাদির শর্ত থেকে এটি স্পষ্ট হয় না। অপ-অপসারণ করতে এবং এটি পরিষ্কারভাবে করার জন্য, আপনি যদি-ক্লজটি ফাংশন থেকে সরিয়ে নিতে চান:

    if [[ "$toC" == / && "$fromC" == / ]] || [[ "$toC" != / && "$fromC" != / ]]
    then
        cdPath=$(chgPath pathA pathB)   # (we moved the conditional outside)

এটি আরও ভাল দেখায়, তবে অনেক সময় আমরা এটি করতে পারি না; আমরা চেকটি ফাংশনের ভিতরেই করাতে চাই।

তাহলে কত ঘন ঘন এটি ঘটে? খুব প্রায়ই না। বছরে এক-দুবার হতে পারে। এটি প্রায়শই ঘটে যায়, আপনার এটি সম্পর্কে সচেতন হওয়া উচিত। আমি যখন এটি মনে করি এটি আমার কোড (ভাষা নির্বিশেষে) এর পাঠযোগ্যতার উন্নতি করে বলে আমি এটি ব্যবহার করা থেকে বিরত হই না।


3
আপনি যদি এর উদ্দেশ্য সম্পর্কে কোনও প্রশ্নের উত্তর দিচ্ছেন তবে আপনার উত্তরটি :ব্যবহার করা উচিত :নয় true। তাই বলা হয়, এখানে শর্তসাপেক্ষ অস্বীকার করার সবচেয়ে সহজ উপায় একটি ব্যবহার হয় [[ ... ]]কমান্ড দিয়ে পূর্বে ভী !: if ! [[ ( ... && ... ) || ( ... && ... ) ]]; then
চ্যানার

1
আহ, খুব সুন্দর, এবং আমার উত্তরটি দেওয়া উচিত। হুমম .... আমি এখনও সেই উদাহরণগুলির কথা ভাবছি যেখানে আমাকে কোনও অপ-শর্ত ব্যবহার করতে হয়েছিল। এটিই আমি নিয়ে এসেছি সেরা।
বিট্টিয়ট

এটা সত্যিই শুধু পিছন সামঞ্জস্য বজায় রাখা হচ্ছে যদিও : ${...=...}তর্কসাপেক্ষে কম বিশ্রী সুদর্শন চেয়ে true ${...=...}। কিছু পাশাপাশি terseness জন্য পছন্দ while :; doকরতে পারে while true; do
চিপনার

2

কিছুটা এই উত্তরের সাথে সম্পর্কিত , আমি পলিগ্লট স্ক্রিপ্টগুলি হ্যাক করার চেয়ে এই অপ-বিকল্পটিকে সুবিধাজনক বলে মনে করি । উদাহরণস্বরূপ, বাশ এবং ভাইসস্ক্রিপ্ট উভয়ের জন্য এখানে একটি বৈধ মন্তব্য রয়েছে:

":" #    this is a comment
":" #    in bash, ‘:’ is a no-op and ‘#’ starts a comment line
":" #    in vimscript, ‘"’ starts a comment line

অবশ্যই, আমরা trueপাশাপাশি ব্যবহার করতে পারি, তবে :একটি বিরামচিহ্ন চিহ্ন এবং অপ্রাসঙ্গিক ইংরেজী শব্দ নয় এটি পরিষ্কার করে দেয় যে এটি একটি বাক্য গঠন টোকেন।


জন্য কেন কেউ একটি বহুভাষিক স্ক্রিপ্ট (ব্যতীত শীতল হচ্ছে) লেখার যেমন একটি চতুর জিনিস করতে হবে: এটা পরিস্থিতিতে সহায়ক প্রমাণ যেখানে আমরা সাধারণত বিভিন্ন ভাষায় বিভিন্ন স্ক্রিপ্ট ফাইল লিখতে হবে, ফাইল সঙ্গে Xফাইল উল্লেখ Y

এমন পরিস্থিতিতে, উভয় স্ক্রিপ্টকে একক, বহুগ্লোট ফাইলে একত্রিত Xকরে পাথ নির্ধারণের জন্য কোনও কাজ এড়ানো যায় নাY (এটি সহজ "$0")। আরও গুরুত্বপূর্ণ বিষয়, এটি প্রোগ্রামটি ঘুরে বেড়ানো বা বিতরণ করা আরও সুবিধাজনক করে তোলে।

  • একটি সাধারণ উদাহরণ। শেবাংগুলির সাথে একটি সুপরিচিত, দীর্ঘস্থায়ী সমস্যা রয়েছে: বেশিরভাগ সিস্টেমে (লিনাক্স এবং সাইগউইন সহ) কেবলমাত্র অনুমতি দেয় একটি যুক্তিকে দোভাষীর কাছে । নিম্নলিখিত শেবাং:

    #!/usr/bin/env interpreter --load-libA --load-libB

    নিম্নলিখিত আদেশটি বরখাস্ত করবে:

    /usr/bin/env "interpreter --load-libA --load-libB" "/path/to/script"

    এবং উদ্দেশ্য না:

    /usr/bin/env interpreter --load-libA --load-libB "/path/to/script"

    সুতরাং, আপনি একটি মোড়ক স্ক্রিপ্ট লিখে শেষ হবে:

    #!/usr/bin/env sh
    /usr/bin/env interpreter --load-libA --load-libB "/path/to/script"

    এখানেই বহুগ্লোসিয়া মঞ্চে প্রবেশ করে।

  • আরও নির্দিষ্ট উদাহরণ। আমি একবার একটি বাশ স্ক্রিপ্ট লিখেছিলাম যা অন্যান্য জিনিসের মধ্যেও ভিমকে অনুরোধ করেছিল। আমার ভিমকে অতিরিক্ত সেটআপ দেওয়া দরকার ছিল, যা বিকল্পের সাহায্যে করা যেতে পারে --cmd "arbitrary vimscript command here"। তবে, সেটআপটি যথেষ্ট ছিল, যাতে এটি একটি স্ট্রিংয়ের সাথে অন্তর্ভুক্ত করা ভয়ানক হত (যদি সম্ভব হয়) possible অতএব, আরও ভাল সমাধান হ'ল এটি কোনও কনফিগারেশন ফাইলে এক্সটেনসোতে লিখতে হবে , তারপরে ভিমকে সেই ফাইলটি পড়তে হবে -S "/path/to/file"। অতএব আমি একটি বহুবৃত্ত বাশ / ভিমস্ক্রিপ্ট ফাইল দিয়ে শেষ করেছি।


1

আমি এটিতে স্ক্রিপ্টগুলি ডিফল্ট ভেরিয়েবলগুলি সংজ্ঞায়িত করতে ব্যবহার করেছি।


: ${VARIABLE1:=my_default_value}
: ${VARIABLE2:=other_default_value}
call-my-script ${VARIABLE1} ${VARIABLE2}

0

মনে করুন আপনার একটি আদেশ রয়েছে যা আপনি অন্যের সাফল্যের সাথে জড়িত হতে চান:

cmd="some command..."
$cmd
[ $? -eq 0 ] && some-other-command

তবে এখন আপনি শর্তসাপেক্ষে আদেশগুলি সম্পাদন করতে চান এবং আপনি যে আদেশগুলি কার্যকর করবেন তা প্রদর্শন করতে চান (শুকনো রান):

cmd="some command..."
[ ! -z "$DEBUG" ] && echo $cmd
[ -z "$NOEXEC" ] && $cmd
[ $? -eq 0 ] && {
    cmd="some-other-command"
    [ ! -z "$DEBUG" ] && echo $cmd
    [ -z "$NOEXEC" ] && $cmd
}

সুতরাং আপনি যদি DEBUG এবং NOEXEC সেট করেন তবে দ্বিতীয় কমান্ড কখনই প্রদর্শিত হবে না। এটি হ'ল কারণ প্রথম কমান্ড কখনই কার্যকর করে না (কারণ নোেক্সইসি খালি নয়) তবে সত্যের মূল্যায়ন আপনাকে 1 এর রিটার্ন দেয়, যার অর্থ অধস্তন কমান্ড কখনই কার্যকর করে না (তবে আপনি এটি চান কারণ এটি একটি শুকনো রান)। সুতরাং এটি ঠিক করতে আপনি একটি নুপ দিয়ে স্ট্যাকের বামে থাকা প্রস্থান মূল্য পুনরায় সেট করতে পারেন:

[ -z "$NOEXEC" ] && $cmd || :
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.