শেলটিতে * .txt সহ প্রসারণ কোনও .txt ফাইল উপস্থিত না থাকলে কাজ করে না


10

আমি প্রসারণ নিয়ে ঘুরে বেড়াচ্ছিলাম, এবং আমি একটি অদ্ভুত আচরণ লক্ষ্য করেছি। আমি চেষ্টা করেছিলাম:

echo ./*.txt

এবং আমার বর্তমান ডিরেক্টরিতে কোনও .txt ফাইল নেই। আমি যে আউটপুট পেয়েছিলাম তা হ'ল:

./*.txt

আমি শুধু কৌতূহলী: কেন আমি এটি পেলাম? আমি কোনও আউটপুট না পাওয়ার প্রত্যাশা করছিলাম।

পিএস: যখন আমার কাছে একটি .txtফাইল ছিল, সম্প্রসারণটি সঠিকভাবে ব্যাখ্যা করা হয়েছিল। অন্য কথায়, বলুন আমার কাছে একটি ফাইল ছিল smthn.txt, প্রতিধ্বনি আসলে প্রতিধ্বনিত হয়েছিল current_directory/smthn.txt

উত্তর:


15

ব্যাশ শেল ম্যান পৃষ্ঠা থেকে মানিয়ে নেওয়া,

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

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


2
আপনি নীচের মত আচরণটি পরিবর্তন করতে পারেন: shopt -s nullglobতুলনামূলক নিদর্শনগুলির জন্য খালি স্ট্রিং দেবে এবং shopt -u nullglob(মানক সেটিং) নিজেই প্যাটার্নটি উত্পাদন করবে।
পার্লডাক

13

আমি কোনও আউটপুট না পাওয়ার প্রত্যাশা করছিলাম।

যদি nullglobডিফল্ট হয়, তবে অনেকগুলি কমান্ডগুলি অপ্রত্যাশিতভাবে আচরণ করবে, কারণ এটি (সম্ভবত দুর্ভাগ্যক্রমে) সাধারণ যে কমান্ডগুলি শূন্য ফাইলের নাম আর্গুমেন্টগুলির ক্ষেত্রে এক বা একাধিক ফাইলের নাম আর্গুমেন্টের চেয়ে গুণগতভাবে আলাদাভাবে আচরণ করে ।

মনে করুন আপনি সক্ষম করেছেন nullglob( shopt -s nullglob) এবং আপনি এমন একটি ডিরেক্টরিতে রয়েছেন যেখানে কোনও ফাইল মিলছে না *.txt। তারপরে *.txtসত্যিকার অর্থে কিছুই প্রসারিত হবে - খালি ক্ষেত নয়, ক্ষেত্র মোটেও নয় - যেমনটি আপনি প্রত্যাশা করেছিলেন। তবে তার এই ফলাফলগুলি হবে:

  • ls *.txtবর্তমান ডিরেক্টরিতে সমস্ত ফাইল (লুকানো ফাইল বাদে) তালিকাভুক্ত করা হবে কারণ lsআপনি যখন কোনও ফাইলের নাম আর্গুমেন্টটি পাস না করেন এটিই ঘটে।
  • cat *.txtস্ট্যান্ডার্ড ইনপুট থেকে পড়তে হবে , কারণ যখন catকোনও ফাইলের নাম আর্গুমেন্ট নেই, এটি যেন আপনি দৌড়েছিলেন cat -। ইন্টারেক্টিভভাবে চলতে থাকলে, এটি ইনপুটটির অপেক্ষায় বসে থাকে। অনেক কমান্ড এইভাবে আচরণ করে।
  • cp *.txt dest/ত্রুটি সঙ্গে ব্যর্থ হবে cp: missing destination file operand after 'dest/'। এটি কোনও বিপর্যয় নয়, তবে এটি বিভ্রান্তিকর এবং সম্ভবত পছন্দসই নীরব সাফল্যের থেকে পৃথক।
  • file *.txt, এবং শূন্য ফাইলনাম আর্গুমেন্টগুলির ক্ষেত্রে বিশেষ আচরণ ছাড়াই অন্যান্য বিভিন্ন প্রোগ্রাম , তবুও কোনওটি পাস না হলে ত্রুটি বা ব্যবহারের বার্তা দিয়ে ব্যর্থ হবে।
  • এমন ঘটনাও যা স্বজ্ঞাতভাবে অনুভব করে যে তাদের প্রায়শই কাজ করা উচিত নয়। কিছুই পরিবর্তে printf 'Got file: "%s"\n' *.txtমুদ্রণ Got file: ""হবে।
  • এর ঘটনার উদ্ধৃত করা আপতিক ব্যর্থতা *, ?এবং [যে নেই শেল দ্বারা প্রসারিত করা আরো প্রায়ই স্পষ্টত ভুল ফল, কিন্তু উপায় আছে জিনিসটা কঠিন হতে পারে উদ্দেশ্যে। উদাহরণস্বরূপ, যদি বর্তমান ডিরেক্টরিতে কোনও ফাইলের নাম দিয়ে শুরু না করা হয় gedit, তবে apt list gedit*(যেখানে apt list 'gedit*'উদ্দেশ্য ছিল) ন্যায়বিচারে পরিণত হবে apt listএবং সমস্ত উপলব্ধ প্যাকেজ তালিকাবদ্ধ করবে।

সুতরাং এটি ভাল যে আপনি অনুরোধ না করে এই আচরণটি পান না। সম্ভবত সবচেয়ে সাধারণ ব্যবহারিক পরিস্থিতি যা আসলে দ্বারা সরলীকৃত nullglobহয় for f in *.txt। আরও দেখুন এই প্রশ্নের (যার Sergiy Kolodyazhnyy এর উত্তর লিঙ্ক)।

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


আমি মনে করি এটি বিষয়টির ন্যূনতম historতিহাসিকভাবে প্রভাবশালী দিক তাই এটি আমি শেষের জন্য সংরক্ষণ করেছি ... তবে এটি উল্লেখ করার মতো যে nullglobআচরণ সম্পর্কে কিছুটা ধারণামূলক মতবিরোধ আছে ।

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

এবং তবুও, আরও একটি সূক্ষ্ম অসঙ্গতি যা সম্বোধন nullglobকরে না - যা এটি প্রকৃতপক্ষে প্রসারিত করে। শূন্য গ্লোব্বিং চরিত্রগুলির ক্ষেত্রে ("ওয়াইল্ডকার্ডস") এক, দুটি বা অন্য যে কোনও সংখ্যার চেয়ে গভীরভাবে বিবেচিত হয়। উদাহরণস্বরূপ, এর সাথে shopt -s nullglob, যদি ab?d?fকোনও ফাইলের সাথে মেলে না, এটি সরানো হবে; যদি ab?dকোনও ফাইলের সাথে মেলে না, এটি সরানো হবে; তবে যদি abকোনও ফাইলের সাথে মেলে না (যেমন কোনও ফাইল নেই যার নাম ঠিক আছে ab) তা এখনও সরানো হয়নি। অবশ্যই, এটি অপসারণ করা হলে এটি একটি বিপর্যয় হবে, কারণ এটি সম্ভবত বর্তমান ডিরেক্টরিতে বিদ্যমান ফাইলটি উল্লেখ করার উদ্দেশ্যে নয়; এটি এমনকি কোনও ফাইলকেও উল্লেখ করতে পারে না। তবে এটি এখনও সম্পূর্ণ ধারাবাহিকতার জন্য কোনও আশা বাদ দেয়।

তিনটি আচরণ বাশ প্রদান করে - গ্লোবগুলির সাথে চিকিত্সার ডিফল্ট যা কোনও ফাইলের সাথে মেলে না যদিও সেগুলি গ্লোব ছিল না এবং তাদেরকে অপ্রস্তুত করে দেওয়া হয়, আপনি যে আচরণটি তাদের চিকিত্সা করার প্রত্যাশা করেছিলেন (যদি আপনি এই শব্দগুচ্ছটির ক্ষমাটি ক্ষমা করেন) ( nullglob) এর সাথে মেলে না এমন ফাইলগুলির সমস্ত শূন্য এবং তাদের ত্রুটিগুলি বিবেচনা করার নিরাপদ আচরণ হিসাবে চিহ্নিত করে ( failglob) - এগুলি শেলের মধ্যে অন্তর্নিহিত অস্পষ্টতার বিভিন্ন পদ্ধতির প্রতিনিধিত্ব করে যে কোনও নির্দিষ্ট শব্দকে উদ্দেশ্য করে কিনা তা জানতে সক্ষম হচ্ছে না being ফাইলের নাম। আপনি যে বিশেষ কমান্ডগুলির সাথে এটি কল করেন তাদের আর্গুমেন্টগুলি কীভাবে আচরণ করবে তা অজান্তে শেলটি তার প্রসার সম্পাদন করে।

উদ্বেগ পৃথকীকরণের এটি অন্যতম উদাহরণ । যেসব সিস্টেমে ইউনিক্স দর্শনের অনুসরণ করা হয়েছে, প্রতিটি অংশে একটি কাজ করা এবং এটি ভালভাবে পরিচালনার উদ্দেশ্যে করা হয় । শেল পাঠ্যগুলি কমান্ড এবং আর্গুমেন্টে প্রসেস করে এবং সেই কমান্ডগুলি আহ্বান করে, যার বেশিরভাগই খোলের বাহ্যিক। এটি বাহ্যিক কমান্ডগুলি সেই রূপান্তরগুলি সম্পাদন করার জন্য নিজেরাই দায়বদ্ধ (ডস এবং উইন্ডোজে প্রচলিত কমান্ড প্রসেসরের মতো) সিস্টেমগুলির তুলনায় অনেক বেশি সুন্দর এবং বহুমুখী হতে থাকে । তবে এর মাঝে মাঝে ডাউনসাইড রয়েছে।


স্পষ্টতই, bash-4.3.39 (2) নেই failglob। সুতরাং এটি ডিফল্ট হতে পারে না কারণ এটি সর্বদা সমর্থিত নয়।
জুলান

6

মূল কারণটি হ'ল এটি পসিক্স দ্বারা নির্দিষ্ট স্ট্যান্ডার্ড আচরণ - সেই মান যা শেল কমান্ডের ভাষা এবং অন্যান্য জিনিসগুলির মধ্যে প্যাটার্ন ম্যাচিংয়ের অন্তর্ভুক্ত থাকে (শেল যেমন bash, dashশেল - উবুন্টুর ডিফল্ট /bin/sh, এবং kshএই মানটি অনুসরণ করে)। বিভাগের ২.১13.৩ প্যাটার্ন থেকে ফাইলের নাম প্রসারণের জন্য ব্যবহৃত প্যাটার্ন :

যদি প্যাটার্নটি কোনও বিদ্যমান ফাইলের নাম বা পাথের সাথে মেলে না, তবে প্যাটার্নের স্ট্রিংটি অপরিবর্তিত রাখা হবে।

এটির অবশ্যই একটি পার্শ্ব প্রতিক্রিয়া রয়েছে - ফাইলের সাথে মিল রয়েছে যা আক্ষরিক হতে পারে *.txt। এতে এবং এতে nullglobবিকল্পটি সহায়তা করতে পারে: যদি সেই বিকল্পটি এর মাধ্যমে সক্ষম করা হয় (এবং এটি এই ডিফল্টরূপে সক্ষম হয় না যা এই প্রশ্নের ক্ষেত্রে প্রযোজ্য), কোনও ফাইলের নাম না পাওয়া গেলে গ্লোবস্টার খালি স্ট্রিংয়ে প্রসারিত হবে। এর নিজস্ব উন্নত প্যাটার্ন মেলানো প্রক্রিয়া রয়েছে যা একই প্রভাব অর্জন করেbashzshshopt -s nullglobksh93~(N)*.txt

আরও দেখুন কেন নাল্লব্লবটি ডিফল্ট নয়?

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