ভবিষ্যতে পরিবর্তিত হলে ক্ষতি করার বিরুদ্ধে বাশ স্ক্রিপ্টগুলি কীভাবে শক্ত করতে পারি?


46

সুতরাং, আমি আমার হোম ফোল্ডারটি মুছে ফেলেছি (বা আরও স্পষ্টভাবে, আমার কাছে সমস্ত লেখার প্রবেশাধিকার রয়েছে)। যা ঘটেছিল তা আমার ছিল

build="build"
...
rm -rf "${build}/"*
...
<do other things with $build>

একটি বাশ স্ক্রিপ্টে এবং, আর প্রয়োজনের পরে $build, ঘোষণা এবং এর সমস্ত ব্যবহারগুলি সরিয়ে ফেলুন - তবে rm। বাশ সুখে প্রসারিত rm -rf /*। হ্যাঁ।

আমি বোকা বোধ করলাম, ব্যাকআপটি ইনস্টল করেছি, আমি যে কাজটি হারিয়েছি তা আবার নতুন করে দিয়েছি। লজ্জার অতীত সরানোর চেষ্টা করা।

এখন, আমি অবাক হই: বাশ স্ক্রিপ্টগুলি লেখার কৌশলগুলি কী কী যাতে এরকম ভুল না ঘটে, বা কমপক্ষে সম্ভাবনা কম থাকে? উদাহরণস্বরূপ, আমি লিখেছিলাম

FileUtils.rm_rf("#{build}/*")

একটি রুবি লিপিতে, দোভাষী দোষী buildনা হওয়ার বিষয়ে অভিযোগ করতেন , সুতরাং সেখানে ভাষাটি আমাকে রক্ষা করে।

আমি বাশে কী বিবেচনা করেছি, জরাজীকরণ ছাড়াও rm(যা সম্পর্কিত প্রশ্নের উত্তর হিসাবে উল্লেখ করা যায় তা অমূলক নয়):

  1. rm -rf "./${build}/"*
    এটি আমার বর্তমান কাজ (একটি গিট রেপো) মেরে ফেলত তবে অন্য কিছুই না।
  2. rmবর্তমানের ডিরেক্টরিগুলির বাইরে কাজ করার সময় এর একটি বৈকল্পিক / পরামিতি ইন্টারঅ্যাকশন প্রয়োজন। (কোনও সন্ধান করতে পারেনি)) অনুরূপ প্রভাব।

এটি কি এটি, বা বাশ স্ক্রিপ্টগুলি লেখার অন্যান্য উপায় রয়েছে যা এই অর্থে "মজবুত"?


3
rm -rf "${build}/*উদ্ধৃতি চিহ্নগুলি কোথায় যায় সে বিষয়টি নিয়ে কোনও কারণ নেই। rm -rf "${build} কারণ একই জিনিস করবে f
মন্টি হার্ড

1
শেলচেক.নেটের সাথে স্থির চেকিং শুরু করার জন্য খুব শক্ত জায়গা। এডিটর একীকরণ উপলব্ধ আছে, তাই আপনি এখনও ব্যবহৃত কিছু সংজ্ঞা মুছে ফেলার সাথে সাথে আপনি আপনার সরঞ্জাম থেকে একটি সতর্কতা পেতে পারে।
চার্লস ডাফি

@ চার্লসডুফি আমার লজ্জা যোগ করার জন্য, আমি সেই স্ক্রিপ্টটি আইডিইএ-স্টাইলের আইডিইতে লিখেছিলাম বাশসপোর্ট ইনস্টলড, যা এই ক্ষেত্রে সতর্ক করে না। সুতরাং হ্যাঁ, বৈধ পয়েন্ট, তবে আমার সত্যিই একটি কঠিন বাতিল প্রয়োজন।
রাফেল

2
Gotcha। বাশফ্যাঙ্ক # 112-ক্যাভেটগুলি নোট করতে ভুলবেন না । set -uপ্রায় হিসাবে তেমন frowned না set -e, কিন্তু এটি এখনও এর getchas আছে।
চার্লস ডাফি

2
কৌতুকের উত্তর: কেবল #! /usr/bin/env rubyপ্রতিটি শেল স্ক্রিপ্টের শীর্ষে রাখুন এবং বাশ সম্পর্কে ভুলে যান;)
পড

উত্তর:


75
set -u

অথবা

set -o nounset

এটি আনসেট ভেরিয়েবলের বর্তমান শেল ট্রিট প্রসারণকে ত্রুটি হিসাবে পরিণত করবে:

$ unset build
$ set -u
$ rm -rf "$build"/*
bash: build: unbound variable

set -uএবং set -o nounsetহয় POSIX শেল অপশন

একটি খালি মান যদিও ত্রুটি ট্রিগার করবে না

তার জন্য, ব্যবহার করুন

$ rm -rf "${build:?Error, variable is empty or unset}"/*
bash: build: Error, variable is empty or unset

সম্প্রসারণ ${variable:?word}মান প্রসারিত হবে variableযদি না তা খালি থাকা অথবা সেট না করে। যদি এটি খালি বা আনসেট না করা থাকে wordতবে এটি স্ট্যান্ডার্ড ত্রুটিতে প্রদর্শিত হবে এবং শেলটি প্রসারণটিকে একটি ত্রুটি হিসাবে বিবেচনা করবে (কমান্ডটি কার্যকর হবে না, এবং যদি একটি ইন্টারেক্টিভ শেলটিতে চলতে থাকে তবে এটি সমাপ্ত হবে)। :আউট ছেড়ে যাওয়া ত্রুটিটি কেবল একটি আনসেট মানের জন্য ঠিক যেমন নীচের দিকে চালিত করে set -u

${variable:?word}একটি পসিক্স প্যারামিটার সম্প্রসারণ

এর কোনওটিই set -e(বা set -o errexit) কার্যকর না হওয়া অবধি একটি ইন্টারেক্টিভ শেলকে শেষ করতে পারে না । ${variable:?word}পরিবর্তনশীল খালি বা আনসেট না থাকলে স্ক্রিপ্টগুলি প্রস্থান করতে পারে। set -uযদি একসাথে ব্যবহার করা হয় তবে স্ক্রিপ্টটি প্রস্থান করতে পারে set -e


আপনার দ্বিতীয় প্রশ্ন হিসাবে। rmবর্তমান ডিরেক্টরিটির বাইরে কাজ না করার সীমাবদ্ধতার কোনও উপায় নেই ।

জিএনইউ এর বাস্তবায়নের rmএকটি --one-file-systemবিকল্প রয়েছে যা এটিকে পুনরাবৃত্তভাবে মাউন্ট করা ফাইল সিস্টেমগুলি মুছে ফেলা থেকে বিরত করে, তবে এটি আমার কাছে যতটা বিশ্বাস করি আমরা rmকার্যত আর্গুমেন্টগুলি যাচাই করে এমন কোনও ফাংশনে কল মোড়ানো ছাড়া পেতে পারি ।


পার্শ্ব দ্রষ্টব্য হিসাবে: প্রসারটি স্ট্রিংয়ের অংশ হিসাবে উপস্থিত না হওয়া পর্যন্ত ${build}হুবহু সমান $buildযেখানে তত্ক্ষণাত্ নীচের অক্ষরটি একটি চলক নামের যেমন একটি বৈধ অক্ষর, যেমন "${build}x"


অনেক ভাল ধন্যবাদ! 1) এটা ${build:?msg}নাকি ${build?msg}? ২) বিল্ড স্ক্রিপ্টগুলির মতো কোনও প্রসঙ্গে, আমি মনে করি নিরাপদ মোছার জন্য আরএম এর চেয়ে আলাদা কোনও সরঞ্জাম ব্যবহার করা ভাল হবে: আমরা জানি আমরা বর্তমান ডিরেক্টরিটির বাইরে কাজ করতে চাই না, তাই আমরা একটি সীমাবদ্ধ ব্যবহার করে তা স্পষ্ট করে তুলি কমান্ড। সাধারণভাবে আরএম নিরাপদ করার দরকার নেই।
রাফেল 13

1
@ রাফেল দুঃখিত, এর সাথে থাকা উচিত :. আমি এখন সেই টাইপো সংশোধন করব এবং আমি আমার কম্পিউটারে ফিরে আসার পরে এর তাত্পর্য উল্লেখ করব।
কুসালানন্দ

2
@ রাফেল ওকে, আমি ব্যতীত কী ঘটে যায় সে সম্পর্কে একটি সংক্ষিপ্ত বাক্য যুক্ত করেছি :(এটি কেবল আনসেট ভেরিয়েবলের জন্য ত্রুটিটি ট্রিগার করবে )। আমি এমন কোনও সরঞ্জাম লেখার চেষ্টা করব না যা নির্দিষ্ট পরিস্থিতিতে সমস্ত পরিস্থিতিতে ফাইলগুলি মুছে ফেলার সাথে মোকাবেলা করতে পারে। পাথগুলি পার্সিং করা এবং প্রতীকী লিঙ্কগুলি ইত্যাদির যত্ন নেওয়া / যত্ন না করা এই মুহুর্তে আমার কাছে কিছুটা স্পষ্টভাবে।
কুসালানন্দ

1
ধন্যবাদ, ব্যাখ্যা সাহায্য করে! "স্থানীয় আরএম" সম্পর্কিত: আমি বেশিরভাগই মশগুল ছিলাম, সম্ভবত একটি "নিশ্চিত, এটি <টুলনাম>" - এর জন্য মাছ ধরছিলাম - তবে অবশ্যই এটি লেখার জন্য আপনাকে সাহায্য-ভ্যাম্পায়ার করার চেষ্টা করছে না! ওহ ভাল, আপনি যথেষ্ট সাহায্য করেছেন! :)
রাফেল

2
@ ম্যাটিউজকনিএকজেনি আমি মনে করি না আমি দুঃখিত, দুঃখিত। আমি বিশ্বাস করি যে প্রয়োজনের সময় এই জাতীয় সুরক্ষা ব্যবস্থা ব্যবহার করা উচিত । পরিবেশকে সুরক্ষিত করে তোলে এমন সমস্ত কিছুর সাথে এটি শেষ পর্যন্ত মানুষকে আরও বেশি অসতর্ক এবং সুরক্ষা ব্যবস্থার উপর নির্ভরশীল করে তুলবে। প্রতিটি সুরক্ষা পরিমাপ কী করে তা জেনে রাখা এবং তারপরে প্রয়োজনীয়তার সাথে বেছে বেছে প্রয়োগ করুন apply
কুসালানন্দ

12

আমি test/ ব্যবহার করে সাধারণ বৈধতা যাচাইয়ের প্রস্তাব দিতে যাচ্ছি[ ]

আপনি যদি আপনার স্ক্রিপ্টটি লিখতেন তবে আপনি নিরাপদ থাকতেন:

build="build"
...
[ -n "${build}" ] || exit 1
rm -rf "${build}/"*
...

যে [ -n "${build}" ]চেকগুলি "${build}"একটি শূন্য-দৈর্ঘ্যের স্ট্রিং

||লজিক্যাল বা ব্যাশ মধ্যে অপারেটর। এটি প্রথম কমান্ড ব্যর্থ হলে এটি অন্য কমান্ডটি চালিত করে।

এইভাবে, ${build}খালি / অপরিশোধিত / ইত্যাদি ছিল। স্ক্রিপ্টটি বেরিয়ে আসত (1 এর রিটার্ন কোড সহ, যা একটি সাধারণ ত্রুটি)।

আপনি সমস্ত ব্যবহার মুছে ফেলার ক্ষেত্রে এটি আপনাকে সুরক্ষিত করতে পারে ${build}কারণ [ -n "" ]সর্বদা মিথ্যা হবে।


ব্যবহার করার সুবিধা test/ এর [ ]আরও অনেক অর্থপূর্ণ চেক রয়েছে যা এটি ব্যবহার করতে পারে।

উদাহরণ স্বরূপ:

[ -f FILE ] True if FILE exists and is a regular file.
[ -d FILE ] True if FILE exists and is a directory.
[ -O FILE ] True if FILE exists and is owned by the effective user ID.

ফর্সা, কিন্তু একটি বাচ্চা অকার্যকর। আমি কি কিছু মিস করছি, বা ${variable:?word}@ কুসালানন্দের প্রস্তাব মতো এটিও বেশ কিছু ?
রাফেল

@ রাফেল এটি "স্ট্রিংয়ের একটি মান রাখে" এর ক্ষেত্রে একইভাবে কাজ করে তবে test(যেমন [) প্রাসঙ্গিক অনেকগুলি চেক রয়েছে যেমন -d(আর্গুমেন্ট একটি ডিরেক্টরি), -f(আর্গুমেন্টটি একটি ফাইল), -O(ফাইল বর্তমান ব্যবহারকারীর মালিকানাধীন) এবং তেমন।
সেন্টিমানে

1
@ রাফেল এছাড়াও, বৈধতা যে কোনও কোড / স্ক্রিপ্টগুলির একটি সাধারণ অংশ হওয়া উচিত। আরও মনে রাখবেন, আপনি যদি বিল্ডিংয়ের সমস্ত দৃষ্টান্ত সরিয়ে ফেলেছেন তবে আপনি কি ${build:?word}এটির সাথে অপসারণ করবেন না? ${variable:?word}বিন্যাস আপনি পরিবর্তনশীল সকল দৃষ্টান্তকে সরাবে আপনি রক্ষা করে না।
সেন্টিমানে

1
1) আমি মনে করি অনুমানগুলি ধরে রাখার (ফাইলগুলির উপস্থিতি ইত্যাদি) নিশ্চিত করার এবং ভেরিয়েবলগুলি সেট করা আছে কিনা তা যাচাই করার মধ্যে (পার্থক / ইন্টারপ্রেটারের imho চাকরি) পার্থক্য রয়েছে think যদি আমাকে পরে যদি তা করতে হয় তবে এর জন্য আরও অতি-স্নাজি সিনট্যাক্স থাকতে হবে - যা পুরোপুরি বিকশিত ifনয়। 2) "আপনি কি সেইসাথে {{বিল্ড:? শব্দ removedও সরিয়ে ফেলতেন না" - দৃশ্যপটটি হ'ল আমি ভেরিয়েবলটির ব্যবহার মিস করেছি। ব্যবহার ${v:?w}আমাকে ক্ষতি থেকে রক্ষা করতে পারে। আমি যদি সমস্ত ব্যবহার সরিয়ে ফেলতাম তবে স্পষ্টতই সরল অ্যাক্সেসও ক্ষতিকারক হত না।
রাফেল

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

4

আপনার নির্দিষ্ট ক্ষেত্রে, আমি এর পরিবর্তে ফাইল / ডিরেক্টরি সরানোর জন্য অতীতে 'মুছে ফেলা' পুনরায় কাজ করেছি (ধরে নিই / টিএমপি আপনার ডিরেক্টরিতে একই পার্টিশনে রয়েছে):

# mktemp -d is also a good, reliable choice
trashdir=/tmp/.trash-$USER/trash-`date`
mkdir -p "$trashdir"
...
mv "${build}"/* "$trashdir"
...

পর্দার আড়ালে, এটি শীর্ষস্থানীয় ফাইল / দির রেফারেন্সগুলি উত্স থেকে $trashdirগন্তব্য ডিরেক্টরি স্ট্রাকচারের সমস্ত একই পার্টিশনে স্থানান্তরিত করে এবং ডিরেক্টরি কাঠামোটি হাঁটাতে এবং ঠিক তখন এবং সেখানে প্রতি-ফাইল ডিস্ক ব্লকগুলি মুক্ত করতে সময় ব্যয় করে না। সিস্টেমটি সক্রিয় ব্যবহারে থাকা অবস্থায় এটি আরও দ্রুত ক্লিনআপ তৈরি করে, সামান্য ধীর রিবুটের বিনিময়ে (/ টিএমপি রিবুটগুলিতে পরিষ্কার হয়)।

বিকল্পভাবে, পর্যায়ক্রমে পরিষ্কার /tmp/.trash-$USER এ একটি ক্রোন এন্ট্রি ভরাট থেকে টিএমপি / রক্ষা করবে, প্রক্রিয়াগুলির জন্য (উদাহরণস্বরূপ, বিল্ডস) যেগুলি অনেক বেশি ডিস্কের স্থান গ্রহণ করে। যদি আপনার ডিরেক্টরিটি / tmp হিসাবে আলাদা পার্টিশনে থাকে তবে আপনি নিজের পার্টিশনে একটি অনুরূপ / tmp-জাতীয় ডিরেক্টরি তৈরি করতে পারেন এবং পরিবর্তে ক্রোনটি পরিষ্কার করতে পারেন।

সর্বাধিক গুরুত্বপূর্ণ, যদিও আপনি যদি কোনওভাবে ভেরিয়েবলগুলি সরিয়ে ফেলেন তবে ক্লিনআপটি হওয়ার আগে আপনি সামগ্রীগুলি পুনরুদ্ধার করতে পারেন।


2
"সিস্টেমটি সক্রিয়ভাবে ব্যবহারের সময় এটি আরও দ্রুত পরিচ্ছন্নতা উত্পাদন করে" - এটি কি? আমি ভাবতাম উভয়ই কেবল আক্রান্ত ইনডগুলি পরিবর্তন করার বিষয়ে। অন্য পার্টিশনে থাকলে এটি অবশ্যই দ্রুত হয় না/tmp (আমি মনে করি এটি সর্বদা আমার জন্য, কমপক্ষে ব্যবহারকারীর স্পেসে চালিত স্ক্রিপ্টগুলির জন্য); তারপরে, আবর্জনা ফোল্ডারটি পরিবর্তন করা দরকার (এবং ওএস-পরিচালনা থেকে লাভ হবে না /tmp)।
রাফেল

1
আপনি mktemp -dঅন্য প্রক্রিয়ার অঙ্গুলি (এবং সঠিকভাবে সম্মানের জন্য $TMPDIR) চালিত না করে অস্থায়ী ডিরেক্টরিটি পেতে ব্যবহার করতে পারেন ।
টবি স্পিড 15

আপনার দুজনের কাছ থেকে আপনার সঠিক এবং সহায়ক নোট যুক্ত হয়েছে, ধন্যবাদ। আমি মনে করি আপনি মূলত উত্থাপিত পয়েন্টগুলি বিবেচনা না করেই আমি প্রাথমিকভাবে এটি পোস্ট করেছি।
ব্যবহারকারী 117529

2

ভেরিয়েবলটি অনির্বাচিত হয়ে গেলে ডিফল্ট নির্ধারণের জন্য বাশ প্যারামিটার বিকল্প ব্যবহার করুন, যেমন:

rm -rf $ {পরিবর্তনশীল: - "/ অস্তিত্বহীন"


1

আমি সবসময় আমার বাশ স্ক্রিপ্টগুলি একটি লাইন দিয়ে শুরু করার চেষ্টা করি #!/bin/bash -ue

-eএর অর্থ "প্রথমে অনাবৃত ররে ব্যর্থ ";

-uমানে " ইউ এনডিক্লার্ড ভেরিয়েবলের প্রথম ব্যবহারে ব্যর্থ "।

দুর্দান্ত নিবন্ধে আরও বিশদ খুঁজুন অনানুষ্ঠানিক বাশ স্ট্রাইক মোডটি ব্যবহার করুন (যদি না আপনি ডিবাগিংটি না হারিয়ে থাকেন) । এছাড়াও লেখক ব্যবহার করার পরামর্শ দিচ্ছেন set -o pipefail; IFS=$'\n\t'তবে আমার উদ্দেশ্যগুলির জন্য এটি ওভারকিল।


1

আপনার পরিবর্তনশীলটি সেট করা আছে কিনা তা যাচাই করার জন্য সাধারণ পরামর্শটি এই ধরণের সমস্যাটি প্রতিরোধের জন্য একটি দরকারী সরঞ্জাম। তবে এক্ষেত্রে একটি সহজ সমাধান ছিল।

$buildডিরেক্টরি মুছে ফেলার জন্য সম্ভবত ডিরেক্টরিটির বিষয়বস্তুগুলি গ্লোব করার দরকার নেই তবে প্রকৃত $buildডিরেক্টরিটি নিজেই নয়। সুতরাং আপনি যদি বহিরাগতটি এড়িয়ে যান *তবে একটি আনসেট মানটি পরিবর্তিত হবে rm -rf /যা ডিফল্টরূপে গত দশকে বেশিরভাগ আরএম বাস্তবায়ন সম্পাদন করতে অস্বীকার করবে (যদি আপনি জিএনইউ আরএম --no-preserve-rootবিকল্পের সাহায্যে এই সুরক্ষাটি অক্ষম না করেন )।

/পাশাপাশি চলার বিষয়টি এড়িয়ে যাওয়ার ফলস্বরূপ rm ''ত্রুটি বার্তার ফলস্বরূপ:

rm: can't remove '': No such file or directory

এমনকি যদি আপনার rm কমান্ড সুরক্ষা প্রয়োগ করে না তবে এটি কাজ করে /


-2

আপনি প্রোগ্রামিং ভাষার পদগুলিতে ভাবছেন, তবে বাশ একটি স্ক্রিপ্টিং ভাষা :-) সুতরাং, সম্পূর্ণ ভিন্ন ভাষার উদাহরণের জন্য সম্পূর্ণ ভিন্ন শিক্ষামূলক দৃষ্টান্ত ব্যবহার করুন ।

এক্ষেত্রে:

rmdir ${build}

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

rm -rf ${build}/${parameter}
rmdir ${build}

এখন, আপনি যদি সেখানে কিছু ফাইল বা ডিরেক্টরিগুলি কোনও টেম্প ফাইল বা এমন কিছু স্থাপন করেন যা আপনার করা উচিত নয়, তবে এটি rmdirএকটি ত্রুটি ছুঁড়ে দেবে। এটি সঠিকভাবে পরিচালনা করুন, তারপরে:

rmdir ${build} || build_dir_not_empty "${build}"

এই চিন্তাভাবনাটি আমাকে ভালভাবে পরিবেশন করেছে কারণ ... হ্যাঁ, সেখানে ছিলেন, এটি করেছেন।


6
আপনার প্রচেষ্টার জন্য ধন্যবাদ, তবে এটি পুরোপুরি ছাপিয়ে গেছে। "এই সদস্যরা কী তা আপনি জানেন" অনুমানটি ভুল; সংকলক আউটপুট মনে। make cleanকিছু ওয়াইল্ডকার্ড ব্যবহার করবে (যতক্ষণ না খুব পরিশ্রমী কম্পাইলার প্রতিটি ফাইল তৈরি করে তার তালিকা তৈরি করে)। এছাড়াও, এটি আমার কাছে মনে হয় যে rm -rf ${build}/${parameter}কেবল সমস্যাটি কিছুটা নিচে নামানো হয়েছে।
রাফেল

হুঁ। দেখুন যে কিভাবে পড়া। "আপনাকে ধন্যবাদ, তবে এটি এমন কোনও কারণে যা আমি মূল প্রশ্নে প্রকাশ করি নি তাই আমি কেবল আপনার উত্তরটি প্রত্যাখাত করব না তবে এটি সাধারণ ক্ষেত্রে আরও প্রযোজ্য হওয়া সত্ত্বেও এটিকে হ্রাস করব" " কি দারুন.
ধনী

"আপনি প্রশ্নে যা লিখেছেন তার বাইরে আমাকে অতিরিক্ত অনুমান করা যাক এবং তারপরে একটি বিশেষ উত্তর লিখুন" " * শ্রুগ * (এফআইআইআই, এটি আপনার কোনও ব্যবসায় নয়: আমি হ্রাস করি নি Ar যুক্তিযুক্তভাবে আমার উচিত ছিল, কারণ উত্তরটি কার্যকর ছিল না (আমার পক্ষে, কমপক্ষে)
রাফেল

হুঁ। আমি কোনও অনুমান করিনি, এবং একটি সাধারণ উত্তর লিখেছি । makeপ্রশ্নে মোটেও কিছুই নেই । একটি উত্তর যা কেবলমাত্র প্রযোজ্য তা makeলিখলে খুব নির্দিষ্ট এবং অবাক করা ধারণা হবে um আমার উত্তরটি makeআপনার স্টাফগুলি মুছে ফেলে আপনার নির্দিষ্ট নবজাতকের সমস্যা ব্যতীত সফ্টওয়্যার বিকাশ ব্যতীত অন্যান্য ক্ষেত্রে কাজ করে ।
ধনী

1
কুশলানন্দ আমাকে মাছ ধরতে শিখিয়েছিলেন। আপনি বরাবর এসে বললেন, "যেহেতু আপনি সমভূমিতে বাস করেন, আপনি তার পরিবর্তে গরুর মাংস খান না কেন?"
রাফেল 5
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.