সমস্যা কি
প্রথমত, অনেকগুলি ইউটিলিটির জন্য, আপনার ফাইলের নাম শুরু হওয়ার সাথে একটি সমস্যা থাকবে -। যখন:
sh -c 'inline sh script here' other args
অন্যান্য আর্গুমেন্টগুলি পাস করা হয়েছে inline sh script; সঙ্গে perlসমতুল্য,
perl -e 'inline perl script here' other args
অন্যান্য আরগগুলি প্রথমে ইনলাইন স্ক্রিপ্টে নয়, আরও বেশি বিকল্পের জন্য স্ক্যান করা হয়েছে options সুতরাং, উদাহরণস্বরূপ, যদি -eBEGIN{do something evil}বর্তমান ডিরেক্টরিটিতে কোনও ফাইল বলা হয়,
perl -ne 'inline perl script here;' *
(সাথে বা বাইরে -n) খারাপ কিছু করবে।
অন্যান্য ইউটিলিটিগুলির মতো, এর জন্য কাজটি হচ্ছে বিকল্পগুলির শেষের চিহ্নটি ব্যবহার করে ( --):
perl -ne 'inline perl script here;' -- *
তবে তারপরেও, এটি এখনও বিপজ্জনক এবং এটি / <>দ্বারা ব্যবহৃত অপারেটরের নিচে ।-n-p
বিষয়টি perldoc perlopডকুমেন্টেশনে ব্যাখ্যা করা হয়েছে ।
সেই বিশেষ অপারেটরটি ইনপুটটির একটি লাইন (একটি রেকর্ড, রেকর্ডগুলি ডিফল্টরূপে লাইন হওয়া) পড়তে ব্যবহৃত হয়, যেখানে সেই ইনপুটটি প্রতিটি আর্গুমেন্ট থেকে ঘুরে ফিরে আসে @ARGV।
ইন:
perl -pe '' a b
-pকোডটির while (<>)চারপাশে একটি লুপ বোঝায় (এখানে খালি)।
<>aফাইলটি শেষ হয়ে না যাওয়া এবং তারপরে খোলার আগে প্রথমে রেকর্ডগুলি একবারে এক লাইনে পড়তে হবে b...
সমস্যাটি হ'ল, ফাইলটি খুলতে, এটির প্রথম, অনিরাপদ ফর্মটি ব্যবহার করে open:
open ARGV, "the file as provided"
সেই ফর্মের সাথে যদি তর্ক হয়
"> afile", এটি afileলেখার মোডে খোলে ,
"cmd|", এটি রান করে cmdএবং এটির আউটপুট পড়ে।
"|cmd", আপনি ইনপুটটিতে লেখার জন্য একটি স্রোত খুলেছেন cmd।
উদাহরণস্বরূপ:
perl -pe '' 'uname|'
কল করা ফাইলটির সামগ্রীর আউটপুট দেয় না uname|(পুরোপুরি বৈধ ফাইলের নাম বিটিডব্লিউ), তবে unameকমান্ডের আউটপুট ।
আপনি যদি চালাচ্ছেন:
perl -ne 'something' -- *
এবং কেউ rm -rf "$HOME"|বর্তমান ডিরেক্টরিতে (আবার একটি নিখুঁত বৈধ ফাইলের নাম) নামে একটি ফাইল তৈরি করেছেন (উদাহরণস্বরূপ কারণ সেই ডিরেক্টরিটি অন্যদের দ্বারা একবারে লেখার যোগ্য ছিল, বা আপনি একটি ডজি আর্কাইভ বের করেছেন, বা আপনি কিছু ডডি কমান্ড চালিয়েছেন, বা অন্য কোনও সফ্টওয়্যারের অন্য দুর্বলতা কাজে লাগানো হয়েছিল), তবে আপনি বড় সমস্যায় পড়েছেন। যে সমস্যাগুলিতে এই সমস্যাটি সম্পর্কে সচেতন হওয়া গুরুত্বপূর্ণ সেগুলি হ'ল জনসাধারণের ক্ষেত্রে স্বয়ংক্রিয়ভাবে ফাইলগুলি প্রক্রিয়া করার /tmpসরঞ্জামগুলি (বা এমন সরঞ্জাম যা এই জাতীয় সরঞ্জামগুলির দ্বারা ডাকা যেতে পারে)।
ফাইল নামক > foo, foo|, |fooএকটি সমস্যা আছে। তবে কিছুটা হলেও < fooএবং fooশীর্ষস্থানীয় বা পিছনে থাকা ASCII ব্যবধান অক্ষরগুলি (স্থান, ট্যাব, নিউলাইন, cr ... সহ) এর পাশাপাশি সেই ফাইলগুলির প্রক্রিয়া করা হবে না বা ভুলটি হবে।
এছাড়াও সাবধান থাকুন যে কয়েকটি মাল্টি-বাইট অক্ষর সেটগুলিতে ( ǖবিআইজি 5-এইচএসসিএস-এর মতো) কিছু এনক্রোডিং বাইট 0x7 সিতে শেষ হয় |।
$ printf ǖ | iconv -t BIG5-HKSCS | od -tx1 -tc
0000000 88 7c
210 |
0000002
সুতরাং সেই অক্ষর ব্যবহার করে লোকেলগুলিতে,
perl -pe '' ./nǖ
./n\x88কমান্ডটি চালানোর চেষ্টা perlকরবে যেমন ব্যবহারকারীর লোকালে সেই ফাইলটির নাম ব্যাখ্যা করার চেষ্টা করা হয় না !
চারপাশে কীভাবে ঠিক করবেন / ঠিক করবেন
আফাইক, perlএকবারে এবং সমস্ত সিস্টেম-ব্যাপী সেই অনিরাপদ ডিফল্ট আচরণ পরিবর্তন করতে আপনি কিছুই করতে পারবেন না ।
প্রথমত, সমস্যাটি কেবল ফাইল নামের শুরু এবং শেষের অক্ষরগুলির সাথে ঘটে। সুতরাং, যখন perl -ne '' *বা perl -ne '' *.txtকোনও সমস্যা,
perl -ne 'some code' ./*.txt
কারণ সব আর্গুমেন্ট এখন দিয়ে শুরু করা হয় না ./এবং শেষ .txt(তাই না -, <, >, |, স্থান ...)। আরও সাধারণভাবে, গ্লোবগুলির সাথে প্রিফিক্স করা ভাল ধারণা ./। এটি কল করা -বা -অন্যান্য অনেকগুলি ইউটিলিটি দিয়ে শুরু করা ফাইলগুলির সমস্যাগুলি এড়ানো হয় (এবং এখানে, এর অর্থ আপনার অপশন-এর অপশন ( --) চিহ্নিতকারী আর প্রয়োজন নেই)।
মোড -Tচালু করতে ব্যবহার taintকিছুটা হলেও সহায়তা করে। যদি এই জাতীয় দূষিত ফাইলের মুখোমুখি হয় (তবে কেবলমাত্র ক্ষেত্রে >এবং কেসগুলির |ক্ষেত্রে নয়, <তবে সাদা অংশের জন্য ) এই আদেশটি বাতিল করে দেবে ।
ইন্টারেক্টিভভাবে এই ধরনের কমান্ডগুলি ব্যবহার করার সময় এটি কার্যকর কারণ এটি আপনাকে সতর্ক করে যে কিছু অসুবিধাগুলি চলছে। কিছু স্বয়ংক্রিয় প্রক্রিয়াজাতকরণ করার সময় এটি আকাঙ্ক্ষিত হতে পারে না, কারণ এর অর্থ কেউ কেবল ফাইল তৈরি করে প্রক্রিয়াটিকে ব্যর্থ করে দিতে পারে।
আপনি প্রতি ফাইল প্রক্রিয়া করতে, তাদের নাম নির্বিশেষে চাও, তাহলে আপনি ব্যবহার করতে পারেন CPAN উপর মডিউল (দুর্ভাগ্যবশত সাধারণত ডিফল্ট অনুসারে ইনস্টল করা হয়নি)। এটি একটি খুব সংক্ষিপ্ত মডিউল যা করে:ARGV::readonly perl
sub import{
# Tom Christiansen in Message-ID: <24692.1217339882@chthon>
# reccomends essentially the following:
for (@ARGV){
s/^(\s+)/.\/$1/; # leading whitespace preserved
s/^/< /; # force open for input
$_.=qq/\0/; # trailing whitespace preserved & pipes forbidden
};
};
মূলত, এটি " foo|"উদাহরণস্বরূপ রূপান্তর করে @ আরজিভি স্যানিটাইজ করে "< ./ foo|\0"।
BEGINআপনার perl -n/-pকমান্ডের একটি বিবৃতিতে আপনি এটি করতে পারেন :
perl -pe 'BEGIN{$_.="\0" for @ARGV} your code here' ./*
এখানে আমরা এটি অনুমান ./করা হচ্ছে যা ব্যবহার করা হচ্ছে সরল ।
যে (এবং একটি পার্শ্ব প্রতিক্রিয়া ARGV::readonly) যদিও যে $ARGVমধ্যে your code hereঅনুষ্ঠান NUL চরিত্র trailing।
আপডেট 2015-06-03
perlv5.21.5 এবং তারপরে একটি নতুন <<>>অপারেটর রয়েছে যা এরকম আচরণ করে <>যে এটি বিশেষ প্রসেসিংটি করবে না । যুক্তিগুলি কেবল ফাইলের নাম হিসাবে বিবেচিত হবে। সুতরাং এই সংস্করণগুলির সাথে, আপনি এখন লিখতে পারেন:
perl -e 'while(<<>>){ ...;}' -- *
ফাইলগুলি ওভাররাইট করা বা অপ্রত্যাশিত কমান্ডগুলি চালনার ভয় ছাড়াই (ভুলে যাওয়া --বা ব্যবহার করতে ভুলবেন না ./*)।
-n/ -pএখনও বিপজ্জনক <>ফর্ম ব্যবহার করুন । এবং সতর্কতা অবলম্বনগুলি এখনও অনুসরণ করা হচ্ছে, এর অর্থ এটি অবিশ্বস্ত ডিরেক্টরিগুলিতে ব্যবহার করা নিরাপদ নয়।