নালগ্লোব কেন ডিফল্ট নয়?


61

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

ls *

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

সুতরাং, nullglobডিফল্টরূপে অক্ষম হওয়ার কোনও কারণ আছে কি? যদি তা হয় তবে সে কারণ কী?


13
কেউ একবার খারাপ বাছাই করে যা "আমরা সর্বদা এটি এভাবেই করেছি" তে পরিণত হয়েছিল। সফটওয়্যার জগতের একটি খুব সর্বব্যাপী ঘটনা (কেবল) নয়।
PSkocik

4
আসল কারণ হ'ল নাল্লগ্লাব বিকল্পটি এর আগে উপস্থিত ছিল না। সুতরাং পিছনের সামঞ্জস্য বজায় রাখতে এটি অবশ্যই ডিফল্টরূপে অক্ষম করা উচিত।
প্রধানমন্ত্রী 2Ring

3
যদিও এটি নাল গ্লোবটি নির্দিষ্টভাবে উল্লেখ করে না, গ্লোব্বিংয়ের কিছু ইতিহাস এই উত্তরটির দ্বারা সরবরাহ করা হয়েছে: unix.stackexchange.com/a/136409/22724
স্ট্রংব্যাড

4
আমি কিছু লোকের ধারণা অনুভব করি যে এটি নাল্লগ্লাবটি ডিফল্টরূপে সক্ষম হওয়া উচিত obvious আমি এটা স্পষ্ট মনে করি না। কমান্ড আহ্বানের আগে শেলের মধ্যে সম্প্রসারণ ঘটে happen
কোজিরো 21'15

2
@ কোজিরো কম স্বজ্ঞাত কার কাছে? * এনআইএক্স শেলগুলির সাথে যে কোনও পরিচিতের সাথে যে কেউ জানেন যে *এটি একটি গ্লোব এবং বিদ্যমান ফাইলগুলিতে প্রসারিত হয় ; খালি ডিরেক্টরি গ্লোবগুলিকে আক্ষরিক অর্থে "প্রসারিত" করা হয়েছে এমন কোনও বিশেষ ক্ষেত্রে এটি কীভাবে "স্বজ্ঞাত" *?
কাইল স্ট্র্যান্ড

উত্তর:


78

nullglobবিকল্প (যা BTW একটি হল zshউদ্ভাবন, শুধুমাত্র বছর পরে যোগ bash( 2.0মামলা একটি সংখ্যা আদর্শ হবে না))। এবং lsএকটি ভাল উদাহরণ:

ls *.txt

বা এর আরও সঠিক সমতুল্য:

ls -- *.txt

সঙ্গে nullglobচালানো হবে lsকোন যুক্তি যা হিসাবে গণ্য হবে সঙ্গে ls -- .(বর্তমান ডিরেক্টরির তালিকা) যদি কোন ফাইল মেলে, যা সম্ভবত কলিং চেয়েও কঠিন অপরাধ lsএকটি আক্ষরিক সঙ্গে *.txtআর্গুমেন্ট হিসাবে।

বেশিরভাগ টেক্সট ইউটিলিটিগুলির সাথে আপনার একই সমস্যা রয়েছে:

grep foo *.txt

ফাইল fooনা থাকলে স্টিডিনে খোঁজ করতেন txt

আরও বুদ্ধিমান ডিফল্ট এবং csh, tcsh, zsh বা માછલી ২.৩++ (এবং প্রথমদিকে ইউনিক্স শেলগুলির) হ'ল গ্লোব মেলে না গেলে কমান্ডটি পুরোপুরি বাতিল করতে হবে।

bash(যেহেতু সংস্করণ 3) এর জন্য একটি failglobবিকল্প রয়েছে (এই আলোচনার জন্য আকর্ষণীয়, বিপরীতে ash, এটি অ্যান্ড টি kshবা zsh, bashবিকল্পগুলির জন্য স্থানীয় স্কোপগুলিকে সমর্থন করে না (যদিও এটি ৪.৪-এ পরিবর্তিত হবে)), যখন বিকল্পটি বিশ্বব্যাপী সক্ষম হয় তখন কয়েকটি জিনিস ভাঙে বাশ-সমাপ্তির ফাংশনগুলির মতো)।

মনে রাখবেন যে, csh শেল এবং tcsh শেল থেকে সামান্য ভিন্ন zsh, fishবা bash -O failglobমত ক্ষেত্রে:

ls -- *.txt *.html

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

ls -- file.txt

আপনার সাথে যে আচরণ পেতে পারেন zshসঙ্গে setopt cshnullglobযদিও এটি না করার জন্য আর যুক্তিসম্মত উপায় zshমত একটি উল্লিখিত glob ব্যবহার করতে হবে:

ls -- *.(txt|html)

ইন zshএবং ksh93, এছাড়াও আপনি আবেদন করতে পারেন nullglob প্রতি উল্লিখিত glob ভিত্তিতে, যা একটি গ্লোবাল সেটিংসকে পরিবর্তন তুলনায় অনেক saner পন্থা করুন:

files=(*.txt(N))  # zsh
files=(~(N)*.txt) # ksh93

txtকোনও ত্রুটিযুক্ত কমান্ড ব্যর্থ করার পরিবর্তে কোনও ফাইল না থাকলে (বা এটি *.txtঅন্যান্য শাঁসের সাথে একটি আক্ষরিক যুক্তি দিয়ে অ্যারে তৈরি করা) যদি একটি ফাঁকা অ্যারে তৈরি করে ।

fish২.৩ এর পূর্ববর্তী সংস্করণগুলি এমনভাবে কাজ করবে bash -O nullglobকিন্তু যখন কোনও গ্লোবের কোনও মিল নেই তখন ইন্টারেক্টিভ করার সময় একটি সতর্কতা দেয়। 2.3 সাল থেকে, এটা মত কাজ করে zshব্যবহার করা globs ছাড়া for, setঅথবা count

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

বোর্ন শেলটিতে করা একটি খারাপ সিদ্ধান্তের কারণে আমরা আজ যে পরিস্থিতিটির মধ্যে আছি।

নোট করুন যে বোর্ন শেল (এবং সি শেল) আরও একটি নতুন ইউনিক্স বৈশিষ্ট্য নিয়ে এসেছে: পরিবেশ। এর অর্থ পরিবর্তনশীল সম্প্রসারণ (এর পূর্বসূরীর কেবলমাত্র $1, $2... অবস্থানগত পরামিতি ছিল)। বোর্ন শেল কমান্ডের প্রতিস্থাপনেরও সূচনা করেছিল।

বোর্ন শেলের আরেকটি দুর্বল নকশার সিদ্ধান্তটি ছিল ভেরিয়েবল এবং কমান্ড প্রতিস্থাপনের বিস্তারের উপর গ্লোববিং (এবং বিভাজন) করা (সম্ভবত থম্পসন শেলের সাথে পশ্চাদপদ সামঞ্জস্যের জন্য যেখানে echo $1এখনও ওয়াইল্ডকার্ড থাকা /etc/globথাকলে অনুরোধ করা হত $1(এটি প্রি-প্রসেসরের ম্যাক্রো বিস্তারের মতো ছিল) সেখানে, প্রসারিত মানটিকে শেল কোড হিসাবে আবার পার্স করা হয়েছিল))।

মেলে না এমন গ্লোবগুলির ব্যর্থতার অর্থ উদাহরণস্বরূপ:

pattern='a.*b'
grep $pattern file

কমান্ডটি ব্যর্থ করবে ( a.whateverbবর্তমান ডিরেক্টরিতে কিছু ফাইল না থাকলে)। csh(যা ভেরিয়েবল প্রসারণ নিয়ে গ্লোব্বিংও করে তোলে) সেক্ষেত্রে কমান্ডটি ব্যর্থ করে (এবং আমি যুক্তি দিয়েছিলাম যে এটি একটি সুপ্ত বাগ ত্যাগ করার চেয়ে ভাল, এমনকি এটি যদি গ্লোব্বিংয়ের মতো না করা যেমন ভাল না হয় তবে zsh)।


আরও একটি ব্যবহারযোগ্যতার সমস্যা রয়েছে: nullglobট্যাব-সমাপ্তি ভাঙার জন্য উপস্থিত হয় (সক্ষম হওয়া অবস্থায় ট্যাব কী টিপলে কিছুই হয় না)।
কাইল স্ট্র্যান্ড

1
বাশ দিয়ে প্রতি গ্লোব ভিত্তিতে নালগ্লোব ব্যবহার করা সম্ভব - যদিও সিনট্যাক্সটি zsh এর মতো মার্জিত নয়files=$(shopt -s nullglob;echo *.txt)
জোন ন্যালি

2
@ জোননলি, এটি ফাইলের নামের সংমিশ্রণ (স্থান সহ) সংরক্ষণ করে (এর সাথে সম্ভাব্য রূপান্তর সহ xpg_echo) স্কেলার ভেরিয়েবলগুলিতে। আপনি ভালো কিছু প্রয়োজন চাই readarray -td '' files < <(shopt -s nullglob; printf '%s\0' *.txt)সঙ্গে bash4.4 বা তার উপরে বা (shopt -s nullglob; printf '%s\0' *.txt) | xargs -r0 cmdগনুহ সঙ্গে xargsযে সব নির্বিচারে ফাইলের নাম দিয়ে ব্যবহারযোগ্য আছি। বা, এখনও bash4.4 সহ, local -বিকল্পের স্থানীয় সুযোগের জন্য (25 বছর পরে ছাই থেকে অনুলিপি করা) সাহায্যকারী ফাংশন ব্যবহার করুন।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.