প্যাট্রিস তার উত্তরে সমস্যার উত্স চিহ্নিত করে , তবে সেখান থেকে কেন আপনি কীভাবে তা পেতে পারেন তা যদি আপনি জানতে চান তবে এখানে দীর্ঘ গল্পটি রয়েছে।
কোনও প্রক্রিয়াটির বর্তমান কার্যকরী ডিরেক্টরি এমন কিছু নয় যা আপনি খুব জটিল মনে করেন। এটি প্রক্রিয়াটির একটি বৈশিষ্ট্য যা টাইপ ডিরেক্টরিগুলির একটি ফাইলের একটি হ্যান্ডেল যেখানে আপেক্ষিক পথগুলি (প্রক্রিয়া দ্বারা নির্মিত সিস্টেম কলগুলিতে) শুরু হয়। আপেক্ষিক পাথটি সমাধান করার সময়, কার্নেলের সেই বর্তমান ডিরেক্টরিটির (ক) সম্পূর্ণ পাথ জানতে হবে না, এটি আপেক্ষিক পাথের প্রথম উপাদানটি আবিষ্কার করার জন্য ডিরেক্টরি ডিরেক্টরি ফাইলের ডিরেক্টরি এন্ট্রিগুলি পড়ে (এবং ..এটি অন্য কোনও মত এই বিষয়ে ফাইল করুন) এবং সেখান থেকে চালিয়ে যান।
এখন, একজন ব্যবহারকারী হিসাবে আপনি কখনও কখনও জানতে চান ডিরেক্টরি ডিরেক্টরিটিতে যে ডিরেক্টরিটি রয়েছে। বেশিরভাগ ইউনিসে, ডিরেক্টরি গাছটি একটি গাছ, লুপ ছাড়া। এটি হ'ল গাছের মূল ( /) থেকে যে কোনও ফাইলের কেবল একটি পথ রয়েছে । সেই পথটিকে সাধারণত ক্যানোনিকাল পাথ বলা হয়।
বর্তমান কার্যনির্বাহী ডিরেক্টরিটির পথ পেতে, একটি প্রক্রিয়া যা করতে হবে তা কেবল হাঁটতে হবে ( নীচে নীচে একটি মূল দেখতে একটি গাছ দেখতে ভাল লাগলে ) গাছটি মূলটিতে ফিরে যাবে, নোডের নামগুলি সন্ধান করবে পথে.
উদাহরণস্বরূপ, একটি প্রক্রিয়া এটির বর্তমান ডিরেক্টরিটি আবিষ্কার করার চেষ্টা /a/b/cকরে ..ডিরেক্টরিটি খুলবে (আপেক্ষিক পথ, ..বর্তমান ডিরেক্টরিতে এন্ট্রিটিও) এবং একই ইনড নম্বর সহ টাইপ ডিরেক্টরি ফাইলের সন্ধান করবে ., এটি সন্ধান করুন cমিলছে, তারপরে খোলা হবে ../..এবং এটি খুঁজে পাওয়া পর্যন্ত /। এখানে কোনও অস্পষ্টতা নেই।
যে কি getwd()বা getcwd()সি ফাংশন কি অথবা অন্তত করতে ব্যবহৃত।
আধুনিক লিনাক্সের মতো কিছু সিস্টেমে, সিস্টেমের কল রয়েছে যে বর্তমান ডিরেক্টরিতে ক্যানোনিকাল পাথ ফিরিয়ে আনবে যা কার্নেল স্পেসে অনুসন্ধান করে (এবং আপনার বর্তমান ডিরেক্টরিটি সন্ধান করার অনুমতি দেয় এমনকি এর সমস্ত উপাদানগুলির অ্যাক্সেস না থাকলেও) , এবং এটি getcwd()সেখানে কল করে। আধুনিক লিনাক্সে, আপনি রিডলিংক () অন করে বর্তমান ডিরেক্টরিতে যাওয়ার পথটিও সন্ধান করতে পারেন /proc/self/cwd।
সর্বাধিক ভাষা এবং প্রারম্ভিক শেলগুলি বর্তমান ডিরেক্টরিটিতে পাথ ফেরানোর সময় এটি করে do
আপনার ক্ষেত্রে, আপনি কল করতে পারেন cd aহতে পারে হিসাবে বার হিসাবে আপনি চান, কারণ এটি একটি সিমবলিক লিঙ্ক আছে, .বর্তমান ডিরেক্টরির পরিবর্তন করে না, যাতে সব getcwd(), pwd -P, python -c 'import os; print os.getcwd()', perl -MPOSIX -le 'print getcwd'আপনার ফিরে আসবে ${HOME}।
এখন, সিমলিংকগুলি সমস্ত জটিল করে তুলেছে।
symlinksডিরেক্টরি গাছের মধ্যে লাফ দেওয়ার অনুমতি দিন। ইন /a/b/c, /aবা /a/bবা /a/b/cএকটি সিমিলিংক হয়, তবে এর ক্যানোনিকাল পথটি /a/b/cসম্পূর্ণ আলাদা would বিশেষত, ..প্রবেশ /a/b/cঅবশ্যই অগত্যা নয় /a/b।
বোর্ন শেলটিতে, যদি আপনি এটি করেন:
cd /a/b/c
cd ..
অথবা এমনকি:
cd /a/b/c/..
আপনার শেষ পর্যন্ত কোনও গ্যারান্টি নেই /a/b।
যেমন:
vi /a/b/c/../d
অগত্যা হিসাবে একই হয় না:
vi /a/b/d
kshকোনও একরকম কাজ করার জন্য একটি লজিকাল কারেন্ট ওয়ার্কিং ডিরেক্টরিের একটি ধারণা চালু করে। লোকেরা এটির অভ্যস্ত হয়ে পড়েছিল এবং পসিক্স সেই আচরণটি নির্দিষ্ট করে শেষ করেছিল যার অর্থ আজকাল বেশিরভাগ শাঁস এটিও করে:
জন্য cdএবং pwdbuiltin কমান্ড ( এবং শুধুমাত্র তাদের জন্য (যদিও এছাড়াও popd/ pushdশাঁস তাদের) আছে দিকে), শেল সাম্প্রতিক কাজ করা সংগ্রহের নিজস্ব ধারণা বজায় রাখে। এটি $PWDবিশেষ ভেরিয়েবলে সঞ্চিত ।
যখন তুমি কর:
cd c/d
এমনকি যদি cবা c/d, symlinks হয় যখন $PWDcontaines /a/b, এটা appends c/dশেষ তাই $PWDহয়ে /a/b/c/d। এবং আপনি যখন করবেন:
cd ../e
পরিবর্তে না করে chdir("../e"), এটা করে chdir("/a/b/c/e")।
এবং pwdকমান্ডটি কেবল $PWDভেরিয়েবলের বিষয়বস্তু প্রদান করে ।
এটি ইন্টারেক্টিভ শেলগুলিতে দরকারী কারণ pwdআপনি যেভাবে সেখানে এসেছেন সে সম্পর্কে তথ্য দেয় এমন বর্তমান ডিরেক্টরিতে একটি পথ খুঁজে বের করে এবং যতক্ষণ না আপনি কেবল অন্য কমান্ডের ..পক্ষে যুক্তি হিসাবে ব্যবহার করেন ততক্ষণ cdআপনি অবাক হওয়ার সম্ভাবনা কম থাকে, কারণ cd a; cd ..বা cd a/..সাধারণত আপনাকে ফিরে পাবেন আপনি যেখানে ছিলেন
$PWDআপনি যদি না করেন তবে এখন, সংশোধিত হবে না cd। পরের বার আপনি কল করার আগে cdবা pwdঅনেক কিছু ঘটতে পারে, এর যে কোনও উপাদানটির $PWDনাম পরিবর্তন করা যেতে পারে। বর্তমান ডিরেক্টরিটি কখনই পরিবর্তিত হয় না (এটি সর্বদা একই ইনোড, যদিও এটি মোছা হতে পারে) তবে ডিরেক্টরি ট্রিতে এর পথটি পুরোপুরি পরিবর্তন হতে পারে। getcwd()ডিরেক্টরি গাছের নীচে হাঁটার মাধ্যমে প্রতিবার যখন ডাইরেক্টরিটি ডাকা হয় ততক্ষণ তা তথ্যের তথ্য সর্বদা নির্ভুল হয় তবে পসিক্স শেলগুলি দ্বারা প্রয়োগ করা লজিক্যাল ডিরেক্টরিতে, তথ্যটি $PWDবাসি হয়ে যেতে পারে। তাই দৌড়ানোর সময় cdবা pwd, কিছু শেল তার বিরুদ্ধে রক্ষা করতে চাইতে পারে।
সেই বিশেষ পরিস্থিতিতে আপনি বিভিন্ন শেল সহ বিভিন্ন আচরণ দেখেন।
কেউ কেউ ksh93সমস্যাটিকে সম্পূর্ণ উপেক্ষা করতে পছন্দ করে, তাই আপনি কল করার পরেও ভুল তথ্য ফিরে আসবে cd(এবং আপনি সেখানে যে আচরণটি দেখছেন তা আপনি দেখতে পাবেন না bash)।
কিছু পছন্দ করে bashবা zshচেক করে যে $PWDএটি বর্তমান ডিরেক্টরিতে এখনও একটি পথ cd, তবে তা নয় pwd।
pdksh উভয় উপর পরীক্ষা করে pwdএবং cd(কিন্তু উপরে pwdআপডেট নেই $PWD)
ash(অন্তত একটি ডেবিয়ান পাওয়া) পরীক্ষা নয়, এবং আপনি কি cd a, এটি একটি প্রকৃত করে cd "$PWD/a", তাই যদি বর্তমান ডিরেক্টরী পরিবর্তিত হয়েছে এবং $PWDবর্তমান ডিরেক্টরির আর পয়েন্ট, এটা আসলে পরিবর্তন করা হবে না aডিরেক্টরির বর্তমান ডিরেক্টরির মধ্যে , তবে একটিতে $PWD(এবং এটি উপস্থিত না থাকলে একটি ত্রুটি ফিরিয়ে দিন)।
আপনি যদি এটির সাথে খেলতে চান তবে আপনি এটি করতে পারেন:
cd
mkdir -p a/b
cd a
pwd
mv ~/a ~/b
pwd
echo "$PWD"
cd b
pwd; echo "$PWD"; pwd -P # (and notice the bug in ksh93)
বিভিন্ন শেল মধ্যে।
আপনার ক্ষেত্রে, আপনি ব্যবহার করছেন থেকে bash, একটি পর cd a, bashচেক যে $PWDএখনও বর্তমান ডিরেক্টরী স্থানটিকে চিহ্নিত করে। এটি করার stat()জন্য এটি $PWDএর ইনোড নম্বরটি পরীক্ষা করার মানটির সাথে এটির তুলনা করে .।
তবে যখন $PWDপথটি সন্ধান করতে অনেকগুলি সিমলিংকগুলি সমাধান করা জড়িত থাকে যা stat()কোনও ত্রুটির সাথে ফিরে আসে, তাই শেলটি $PWDএখনও বর্তমান ডিরেক্টরিটির সাথে সামঞ্জস্য কিনা তা পরীক্ষা করতে পারে না , সুতরাং এটি আবার এটির সাথে গণনা করে getcwd()এবং $PWDতদনুসারে আপডেট হয়।
এখন, প্যাট্রিসের উত্তরটি স্পষ্ট করার জন্য, কোনও সন্ধানের সময় সিমলিংকের সংখ্যার যে পরীক্ষার মুখোমুখি হয়েছিল তা হ'ল সিমলিংক লুপগুলি থেকে রক্ষা করা। সবচেয়ে সহজ লুপটি দিয়ে তৈরি করা যায়
rm -f a b
ln -s a b
ln -s b a
সেই নিরাপদ প্রহরী ব্যতীত cd a/x, সিস্টেমে কোন aলিঙ্ক রয়েছে, এটি সন্ধান করতে হবে bএবং এটি একটি সিমলিংক যা লিঙ্ক করেছে aএবং এটি অনির্দিষ্টকালের জন্য চলে। এর বিরুদ্ধে সতর্ক থাকার সহজ উপায় হ'ল স্বেচ্ছাসেবীর সংখ্যার চেয়ে বেশি সংখ্যক সমাধানের পরে সমাধান করা।
লজিকাল বর্তমান ওয়ার্কিং ডিরেক্টরিতে ফিরে যান এবং কেন এটি কোনও বৈশিষ্ট্য এত ভাল নয়। এটি উপলব্ধি করা গুরুত্বপূর্ণ যে এটি কেবল cdশেলের জন্য এবং অন্যান্য কমান্ডের জন্য নয়।
এই ক্ষেত্রে:
cd -- "$dir" && vi -- "$file"
সর্বদা হিসাবে একই হয় না:
vi -- "$dir/$file"
এ কারণেই আপনি মাঝে মাঝে দেখতে পাবেন যে লোকেরা সর্বদা cd -Pবিভ্রান্তি এড়াতে স্ক্রিপ্টগুলিতে ব্যবহার করার পরামর্শ দেয় (আপনি চাইবেন না যে আপনার সফ্টওয়্যার ../xঅন্য কমান্ডের চেয়ে অন্য কোনও যুক্তি হ'ল এটি অন্য ভাষার পরিবর্তে শেলের মধ্যে লেখা হয়েছে)।
-Pবিকল্প অক্ষম হয় লজিক্যাল ডিরেক্টরির হ্যান্ডলিং তাই cd -P -- "$var"আসলে কল নেই chdir()সামগ্রীর উপর $var(-setup যখন $varহয় -কিন্তু যে অন্য গল্প)। এবং এর পরে cd -P, $PWDএকটি ক্যানোনিকাল পাথ থাকবে।