(1) সন্ধান করুন: স্টার ওয়াইল্ডকার্ড কিছু ফাইলের নাম ব্যর্থ হওয়ার জন্য কীভাবে এটি প্রয়োগ করা হয়?


31

একটি ফাইল সিস্টেমে যেখানে ফাইলের নামগুলি ইউটিএফ -8 এ রয়েছে, আমার একটি ত্রুটিযুক্ত নাম সহ একটি ফাইল রয়েছে; এটি D�sinstallerzsh অনুযায়ী প্রকৃত নাম হিসাবে প্রদর্শিত হবে D$'\351'sinstaller:, ল্যাটিন 1 এর জন্য Désinstaller, "আনইনস্টল" এর জন্য একটি ফরাসি বর্বরতা। জেডএস এর সাথে মেলে না [[ $file =~ '^.*$' ]]তবে এটি একটি দুর্যোগের সাথে মিলবে *- এটি আমার প্রত্যাশা আচরণ।

এখন চালানোর সময় আমি এটি find . -name '*'সন্ধানের প্রত্যাশা করছি factএমন সত্য, আমি এই পরীক্ষায় ব্যর্থ হওয়ার জন্য কোনও ফাইলের নাম আশা করব না। তবে, এর সাথে LANG=en_US.utf8ফাইলটি প্রদর্শিত হবে না এবং এটি কাজ করার জন্য আমাকে সেট LANG=C(বা en_US, বা '') করতে হবে।

প্রশ্ন: বাস্তবায়ন পিছনে কী, এবং আমি কীভাবে সেই ফলাফলটি পূর্বাভাস দিতে পারি?

ইনফোস: আর্চ লিনাক্স 3.14.37-1-lts, ফাইন্ড (জিএনইউ সন্ধানী) 4.4.2


1
আপনি convmvফাইলের নামগুলি utf-8 এ রূপান্তর করতে বিবেচনা করেছেন ?
ctrl-alt-delor

@রিচার্ড: আসলে, আমি ফাইলের নামটি [[ $file =~ '^.*$' ]]ব্যবহার করতে ব্যর্থ হওয়ার উপর নির্ভর করে recodeথাকি, তবে এখন convmvপ্রয়োজন হয় কিনা তাও আমি খতিয়ে দেখব । ধন্যবাদ।
মিশাল

উত্তর:


25

এটা সত্যিই একটি দুর্দান্ত ক্যাচ। গনুহ খোঁজ জন্য সোর্স কোড এ দ্রুত বর্ণন থেকে, আমি বলতে হবে কিভাবে এই নিচে boils fnmatch(অবৈধ বাইট ক্রমের উপর আচরণ করবে pred_name_commonমধ্যে pred.c):

b = fnmatch (str, base, flags) == 0;
(...)
return b;

এই কোডটি fnmatch0 এর সাথে সমতার জন্য রিটার্ন মানটি পরীক্ষা করে তবে ত্রুটিগুলি পরীক্ষা করে না; এর ফলে কোনও ত্রুটি "মিলছে না" হিসাবে রিপোর্ট করা হয়েছে in

অনেক বছর আগে, এই লিবিসি ফাংশনের আচরণটি পরিবর্তনের জন্য *, এমনকি ভাঙা ফাইলের নামগুলিতেও প্যাটার্নটিতে সর্বদা সত্য প্রত্যাবর্তনের পরামর্শ দেওয়া হয়েছে , তবে আমি যে ধারণাটি বলতে পারি তা থেকে প্রত্যাখ্যান করা উচিত ( https থেকে শুরু হওয়া থ্রেডটি দেখুন) : //sourceware.org/ML/libc-hacker/2002-11/msg00071.html ):

যখন fnmatch একটি অবৈধ মাল্টিবাইট চরিত্র সনাক্ত করে এটি আবার একক বাইট মেলানো উচিত, যাতে "*" এর সাথে একটি স্ট্রিং মেলানোর সুযোগ থাকে।

এবং কেন এটি আরও ভাল বা আরও সঠিক? বিদ্যমান অনুশীলন আছে?

স্টাফেন চেজেলাস একটি মন্তব্যে এবং একই 2002 থ্রেডে যেমন উল্লেখ করেছেন, এটি শাঁস দ্বারা সম্পাদিত গ্লোব সম্প্রসারণের সাথে সঙ্গতিপূর্ণ নয় যা অবৈধ চরিত্রগুলিতে দম বন্ধ করে না। সম্ভবত আরও বিস্মিত হওয়ার বিষয়টি এই যে পরীক্ষার বিপরীত হওয়া কেবল সেই ফাইলগুলির সাথে মেলে যাঁর নাম ভাঙা হয়েছে (এর সাথে বাশে ফাইল তৈরি করুন touch $'D\351marrer' $'Touch\303\251' $'\346\227\245\346\234\254\350\252\236'):

$ find -name '*'
.
./Touché
./日本語

$ find -not -name '*'
./D?marrer

সুতরাং, আপনার প্রশ্নের উত্তর দেওয়ার জন্য, আপনি fnmatchএই ক্ষেত্রে আপনার আচরণ সম্পর্কে জেনে এবং findএই ফাংশনটির রিটার্ন মানটি কীভাবে পরিচালনা করে তা জেনে আপনি ভবিষ্যদ্বাণী করতে পারেন ; আপনি সম্ভবত ডকুমেন্টেশন পড়ার মাধ্যমে এটি সন্ধান করতে পারেন না।


কেন কোনও স্থিরতা নেই তার জন্য আমার অনুমানটি *তখন এটির সাথে বেমানান D*staller
ctrl-alt-delor

7
@richard, ধারণা হবে যে হবে D*stallerউপর মেলে দিবে $'D\351sinstaller'পাশাপাশি মত এটা সব শাঁস আমি পরীক্ষিত করেছেন উল্লিখিত glob মধ্যে আছে। GNU fnmatch আচরণ GNU শেলের সাথে সামঞ্জস্যপূর্ণ নয় বলে আমি মনে করি এটি একটি বাগ।
স্টাফেন চেজেলাস

1
দারুণ উদাসীন উত্তর, ধাগ; অনেক প্রশংসিত. আপনি কোন এফএনমেচ অনুসারে স্ট্যান্ডার্ড স্পেসটি নির্দেশ করে কিছু মনে করবেন? আমি সাধারণ পসিক্স রেজিএক্সপ স্পেসটি সুনির্দিষ্টভাবে উল্লেখ করতে পারি যা .কেবলমাত্র এনকোডিংয়ে বৈধ অক্ষরের .*সাথেই মিলবে — সুতরাং আমার প্রত্যাশা যা অবৈধ স্ট্রিংগুলির সাথে মেলে না — তবে আমি গ্লোব্বিং স্টারের সাথে কোনও মিল খুঁজে পাচ্ছি না।
মিশেল 22

1
আমি অনলাইনে যে নিকটতম স্পেসিফিকেশনটি পাই তা এই ওপেনগ্রুপ পৃষ্ঠায় । এতে বলা হয়েছে যে মিলটি চরিত্রের এনকোডিংয়ের জন্য ব্যবহৃত বিট প্যাটার্নের ভিত্তিতে হবে, চরিত্রের গ্রাফিক উপস্থাপনার ভিত্তিতে নয়। এবং <মাসিক> একটি প্যাটার্ন যা নাল স্ট্রিং সহ যে কোনও স্ট্রিংয়ের সাথে মেলে। এটি বিতর্কিতভাবে @ স্টাফেনচাজেলাসের পরামর্শ হিসাবে ব্যাখ্যা করা যেতে পারে। 13 বছর পরে, আবার উপচে পড়া পিন করার সময় হতে পারে :-)
মিশেল

@ মাইকেল, আমি এর চেয়ে ভাল আর কিছু পাই না। সম্ভবত, তুলনা করার পয়েন্ট হিসাবে, ম্যাক ওএস-এ জিএনইউ অনুসন্ধান শেলের গ্লোব্বিংয়ের সাথে সামঞ্জস্যপূর্ণ আচরণ করে (যেমন, -name '*'সমস্ত ফাইলের সাথে মেলে, ভাঙা নাম অন্তর্ভুক্ত), সম্ভবত বিএসডি-র সংস্করণ fnmatch, যা পসিক্স ২.২ কনফর্মেন্স দাবি করে না, জিএনইউ সংস্করণটির বিপরীতে, একটি আলাদা এবং যুক্তিযুক্তভাবে স্যানার রয়েছে, অবৈধ অক্ষরগুলিতে কী করা উচিত তার ব্যাখ্যা।
ধাগ

13

এটি -name বিকল্প ব্যবহার শেল প্যাটার্ন ম্যাচিং স্বরলিপি ম্যাচিং ফাইলের নাম সম্পাদন করতে। একাধিক অক্ষরের সাথে মেলে *এমন একটি প্যাটার্ন , এটি শূন্য বা আরও বেশি অক্ষরের একটি স্ট্রিংয়ের সাথে মিলবে

findব্যবহারসমূহ fnmatch প্যাটার্ন ম্যাচিং চেক করতে, তাই আপনি ব্যবহার করতে পারেন ltrace ফলাফলের চেক করতে:

$ touch $'\U1212'aa
$ touch D$'\351'sinstaller
$ LC_ALL=en_US.utf8 ltrace -e fnmatch find -name '*'          
find->fnmatch("foo", "foo", 0)                   = 0
find->fnmatch("Foo", "foo", 0)                   = 1
find->fnmatch("Foo", "foo", 16)                  = 0
find->fnmatch("*", ".", 0)                       = 0
.
find->fnmatch("*", "D\351sinstaller", 0)         = -1
find->fnmatch("*", "\341\210\222aa", 0)          = 0
./ሒaa
+++ exited (status 0) +++

সাথে D\351sinstaller, fnmatchফিরে -1, ইঙ্গিত করে যে এটি মেলে ব্যর্থ। এর মতো বৈধ চরিত্রের ሒaaসাথে মিল থাকবে।

আপনার ক্ষেত্রে, UTF-8লোকেলের সাথে, \351একটি অবৈধ অক্ষর, প্যাটার্নের মিলটি ব্যর্থ হওয়ার কারণ।


3
খুব কমপক্ষে, ব্যবহারের জন্য +1 ltrace। আমি সম্পর্কে জানতাম strace, তবে ltraceআমার কাছে নতুন। বাহ!
মিশেল 22
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.