কোট ছাড়াই ইকো চালানো কি বিপজ্জনক?


11

আমি বেশ কয়েকটি অনুরূপ বিষয় দেখেছি, তবে তারা ভেরিয়েবলগুলি উদ্ধৃত না করে উল্লেখ করছে, যা আমি জানি যে অযাচিত ফলাফল হতে পারে।

আমি এই কোডটি দেখেছি এবং ভাবছিলাম যে কোডের এই লাইনটি কার্যকর হলে কোনও কিছু চালানো ইনজেক্ট করা সম্ভব হয়েছিল:

echo run after_bundle


আমার যখন ছিল তখন আমি এতে দৌড়েছি: টার্গেট = "*** লাইভ সার্ভার ***"; প্রতিধ্বনি লক্ষ্য: $ লক্ষ্য; এবং *** একটি ফোল্ডার তালিকায় বিস্তৃত হয়েছে ... 😬
ম্যাট পার্কিনস

উত্তর:


17

নির্দিষ্ট ক্ষেত্রে

echo run after_bundle

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

"বিপদ" তখনই আসে যখন আপনি পরিবর্তনশীল ডেটা ব্যবহার করেন যা শেলটি প্রসারিত বা ব্যাখ্যা করতে পারে। এই ধরনের ক্ষেত্রে, যত্ন নেওয়া উচিত যে শেলটি সঠিকভাবে কাজ করে এবং ফলাফলটি কী উদ্দেশ্যে করা হয়।

নিম্নলিখিত দুটি প্রশ্নে সে সম্পর্কিত প্রাসঙ্গিক তথ্য রয়েছে:


echoকখনও কখনও এই সাইটের উত্তরে সম্ভাব্য ক্ষতিকারক কমান্ডগুলি "রক্ষা" করতে ব্যবহৃত হয়। উদাহরণস্বরূপ, আমি কীভাবে ফাইলগুলি সরাতে বা ফাইলগুলি কোনও নতুন গন্তব্যে নিয়ে যেতে ব্যবহার করে তা দেখিয়ে দিতে পারি

echo rm "${name##*/}.txt"

অথবা

echo mv "$name" "/new_dir/$newname"

এটি প্রকৃতপক্ষে ফাইলগুলি অপসারণ বা নামকরণের পরিবর্তে টার্মিনালে আউটপুট কমান্ড দেয়। এরপরে ব্যবহারকারী কমান্ডগুলি পরিদর্শন করতে পারেন, ঠিক করেছেন যে তারা ঠিক আছে কিনা, এটি সরান echoএবং আবার চালাতে পারেন ।

আপনার আদেশটি echo run after_bundleব্যবহারকারীর জন্য একটি নির্দেশ হতে পারে, বা এটি "মন্তব্য করা" কোডের টুকরো হতে পারে যা পরিণতিগুলি না জেনে চালানো খুব বিপজ্জনক।

ব্যবহার echoভালো, এক কি পরিবর্তিত কমান্ড করে এবং এক আবশ্যক নিশ্চয়তা পরিবর্তিত কমান্ড আসলে হয়েছে হয় নিরাপদ (এটা সম্ভাব্য হবে না যদি এটা পুনঃনির্দেশগুলি অন্তর্ভুক্ত হতে, এবং একটি পাইপলাইন তে এটি ব্যবহার করছেন না কাজ, ইত্যাদি আছে)


শেল কী করবে তা জানার জন্য উদ্ধৃতি যুক্ত করা যথেষ্ট নয় - তবে আপনি যেমনটি বলতে পারবেন না যে কোনওভাবেই এটির চেয়ে echo rm "first file.txt" "second file.txt"আলাদা echo rm "first" "file.txt" "second" "file.txt", উভয় থেকে আউটপুট একই being যদি আপনি আউটপুট হিসাবে শেল কমান্ড উত্পন্ন করতে চান, একটি অবশ্যই ব্যবহার করতে হবেprintf '%q ' rm "first file.txt" "second file.txt"; echo বা এমন কিছু সমতুল্য যা সিনট্যাকটিক উদ্ধৃতি দিয়ে পুনরায় উত্পন্ন করে যা argvউত্তীর্ণের সাথে মূল্যায়ন করে ।
চার্লস ডাফি

@ চার্লসডুফি আমি সত্যিই প্রত্যাশা করি কেউই ডিবাগিং আউটপুট কপি-পেস্ট করে শেল এ চালায় না!
কুসালানন্দ

1
শেল কমান্ড তৈরি করা এবং তারপরে সেগুলি পাইপ করা shঠিক কোনও অস্বাভাবিক প্যাটার্ন নয় এবং লোকেদের জিজ্ঞাসা করা " fooআমি যখন এটি একটি কমান্ড লাইনে চালিত করি তখন কেন কাজ echoকরে?" " এখানে সব সময় ঘটে । আরও উল্লেখযোগ্য বিষয়, ডিবাগিং আউটপুট সহায়ক না যদি এটি আপনার বাগগুলি আড়াল করে - এবং যদি আপনার বাগগুলি উদ্ধৃতি সম্পর্কিত হয়, তবে echoসেগুলি প্রকাশ করবে না।
চার্লস ডাফি

27

@ কুসালানন্দের সূক্ষ্ম উত্তরের উপরে মাত্র একটি অতিরিক্ত নোট ।

echo run after_bundle

ঠিক আছে কারণ 3 টি আর্গুমেন্টের echoকোনও অক্ষরই শেলটির জন্য বিশেষ এমন অক্ষর ধারণ করে নি।

এবং (অতিরিক্ত পয়েন্টটি আমি এখানে তৈরি করতে চাই) এমন কোনও সিস্টেম লোকেল নেই যেখানে সেই বাইটগুলি শেলের জন্য বিশেষত অক্ষরে অনুবাদ করতে পারে।

এই সমস্ত অক্ষরই পসিক্সের পোর্টেবল অক্ষর সেট হিসাবে রয়েছে । এই অক্ষরগুলি উপস্থিত থাকতে হবে এবং একটি পসিক্স সিস্টেমে সমস্ত অক্ষর সেটগুলিতে একই এনকোড করা উচিত ²

সুতরাং সেই কমান্ড লাইনটি স্থানীয়ভাবে নির্বিশেষে একইভাবে ব্যাখ্যা করা হবে।

এখন, আমরা যদি সেই পোর্টেবল অক্ষর সেটের বাইরে অক্ষরগুলি ব্যবহার শুরু করি, তবে শেলটির জন্য বিশেষ না হলেও তাদের উদ্ধৃতি দেওয়া ভাল ধারণা, কারণ অন্য কোনও লোকেলগুলিতে, তাদের দ্বারা গঠিত বাইটগুলি বিভিন্ন অক্ষর হিসাবে ব্যাখ্যা করা যেতে পারে যা হয়ে উঠতে পারে শেল বিশেষ। মনে রাখবেন যে আপনি ব্যবহার করছেন echoবা অন্য কোনও কমান্ড, সমস্যাটি echoশেল কীভাবে তার কোডটিকে বিশ্লেষণ করে তা নয়।

উদাহরণস্বরূপ একটি ইউটিএফ -8 এ:

echo voilà | iconv -f UTF-8 -t //TRANSLIT

এটি à0xc3 0xa0 হিসাবে এনকোড হয়েছে। এখন, যদি আপনার কাছে শেল স্ক্রিপ্টে কোডটির লাইন থাকে এবং শেল স্ক্রিপ্টটি এমন কোনও ব্যবহারকারী দ্বারা ব্যবহৃত হয় যা লোকেল ব্যবহার করে যার চরসেটটি ইউটিএফ -8 নয়, এই দুটি বাইট খুব আলাদা অক্ষর তৈরি করতে পারে।

উদাহরণস্বরূপ, fr_FR.ISO8859-15লোকালে, একটি আদর্শ ফরাসি লোকাল যা স্ট্যান্ডার্ড সিঙ্গল-বাইট চারসেট ব্যবহার করে যা ফ্রেঞ্চ ভাষা (ইংরেজি সহ বেশিরভাগ পশ্চিমা ইউরোপীয় ভাষার জন্য একই ব্যবহৃত) ব্যবহার করে, যে 0xc3 বাইট Ãঅক্ষর হিসাবে এবং 0xa0 অ অ- হিসাবে ব্যাখ্যা করা হয় ব্রেকিং স্পেস ক্যারেক্টার।

এবং নেটবিএসডি'র মতো কয়েকটি সিস্টেমে, অবিচ্ছেদী স্থানকে একটি ফাঁকা চরিত্র হিসাবে বিবেচনা করা হয় ( isblank()এটির সাথে সত্যটি ফিরে আসে, এটি মিলে যায় [[:blank:]]) এবং সেগুলির মতো শাঁসগুলি bashতাদের সিনট্যাক্সে এটি টোকেন ডিলিমিটার হিসাবে বিবেচনা করে।

যে চলমান পরিবর্তে এর মানে হল যে echoসঙ্গে $'voil\xc3\xa0'আর্গুমেন্ট হিসাবে, তারা সঙ্গে এটি চালানোর $'voil\xc3'যুক্তি, এটা মুদ্রণ করা হবে না যার মানে যেমন voilàসঠিকভাবে।

এটা তোলে BIG5, BIG5-HKSCS, GB18030, GBK মত চীনা অক্ষর সেট যা অনেক অক্ষর যার এনকোডিং হিসাবে একই এনকোডিং রয়েছে সঙ্গে অনেক খারাপ পায় |, `, \(এছাড়াও যে হাস্যকর SJIS (খারাপ নাম), মাইক্রোসফট কাঞ্জি ওরফে ছাড়া এটি এর ¥পরিবর্তে \, তবে \এটি 0x5c হিসাবে এনকোড করা অবস্থায় এখনও বেশিরভাগ সরঞ্জাম হিসাবে বিবেচিত হয়)।

উদাহরণস্বরূপ, যদি zh_CN.gb18030চাইনিজ লোকালে থাকে তবে আপনি স্ক্রিপ্ট লিখুন:

echo  reboot

এই স্ক্রিপ্টটি 詜 rebootজিবি 18030 বা জিবি কে ব্যবহার করে লোকালয়ে, বিআইজি 5 বা বিআইজি 5-এইচকেএসসিএস ব্যবহার করে কোনও লোকালে আউটপুট 唰 rebootআসবে, তবে সিএস লোকলে ASCII ব্যবহার করবে বা আইএসও 8859-15 বা ইউটিএফ -8 ব্যবহার করে লোকালে rebootচালিত হবে কারণ জিবি 18030 এনকোডিং এর 0xd4 0x7c এবং 0x7c হ'ল |ASCII এর এনকোডিং তাই আমরা চলতে শেষ করি:

 echo �| reboot

(যে প্রতিনিধিত্ব করে তবে 0xd4 বাইট লোকালে রেন্ডার করা হয়েছে)। unameপরিবর্তে কম ক্ষতিকারক ব্যবহার করে উদাহরণ reboot:

$ echo $'echo \u8a5c uname' | iconv -t gb18030 > myscript
$ LC_ALL=zh_CN.gb18030 bash ./myscript | sed -n l
\324| uname$
$ LC_ALL=C bash ./myscript | sed -n l
Linux$

( unameচালানো হয়েছিল)

সুতরাং আমার পরামর্শটি হবে পোর্টেবল অক্ষর সেটের বাইরে থাকা সমস্ত স্ট্রিংয়ের উদ্ধৃতি দেওয়া ote

তবে মনে রাখবেন যে যেহেতু এর এনকোডিং \এবং `যারা অক্ষর কিছু এনকোডিং পাওয়া যায়, এটা ভাল না ব্যবহার করবেন তা \বা "..."বা $'...'(অভ্যন্তরীণ যা `এবং / অথবা \এখনও বিশেষ), কিন্তু '...'পরিবর্তে পোর্টেবল অক্ষর সেট বাহিরে অক্ষর উদ্ধৃত করা।

আমি এমন কোনও সিস্টেমের বিষয়ে অবগত নই যেখানে লোকেল রয়েছে যেখানে চরসেটের কোনও অক্ষর রয়েছে ( 'অবশ্যই নিজেরাই ব্যতীত ) যার এনকোডিংটিতে এনকোডিং রয়েছে ', সুতরাং '...'অবশ্যই সেগুলি নিরাপদ হওয়া উচিত।

নোট করুন যে কয়েকটি শেল $'\uXXXX'তাদের ইউনিকোড কোড পয়েন্টের উপর ভিত্তি করে অক্ষর প্রকাশ করতে একটি স্বরলিপি সমর্থন করে। zshএবং এর মতো শেলগুলিতে bash, অক্ষরটি লোকেলের চরসেটে এনকোড করা থাকে (যদিও সেই অক্ষরে অক্ষরে অক্ষর না থাকলে অপ্রত্যাশিত আচরণের কারণ হতে পারে)। এটি আপনাকে আপনার শেল কোডে নন-এএসসিআইআই অক্ষর সন্নিবেশ করা এড়াতে দেয়।

সুতরাং উপরে:

echo 'voilà' | iconv -f UTF-8 -t //TRANSLIT
echo '詜 reboot'

বা:

echo $'voil\u00e0'
echo $'\u8a5c reboot'

(সতর্কতার সাথে এটি স্ক্রিপ্টটি ভেঙে দিতে পারে যখন লোকেলগুলিতে চালিত হয় যেখানে এই অক্ষর নেই)।

বা আরও ভাল, যেহেতু \এটিও বিশেষ echo(বা কমপক্ষে কিছু echo বাস্তবায়ন, কমপক্ষে ইউনিক্স অনুগত):

printf '%s\n' 'voilà' | iconv -f UTF-8 -t //TRANSLIT
printf '%s\n' '詜 reboot'

(মনে রাখবেন যে \এটি প্রথম যুক্তিতেও বিশেষ printf, তাই নন-এএসসিআইআই অক্ষরগুলিতে এনকোডিং থাকতে পারে সেখানে সেগুলি আরও ভালভাবে এড়ানো যায় \)।

আপনি যেটি করতে পারেন তা নোট করুন:

'echo' 'voilà' | 'iconv' '-f' 'UTF-8' '-t' '//TRANSLIT'

(এটি অত্যধিক দক্ষ হবে তবে আপনি যদি কিছু নিশ্চিত না হন যে অক্ষরগুলি বহনযোগ্য চরিত্রের সেটে রয়েছে) তবে আপনাকে কিছুটা মনের শান্তি দিতে পারে)

এছাড়াও নিশ্চিত করুন যে `...`কমান্ড প্রতিস্থাপনের প্রাচীন ফর্মটি (যা ব্যাকস্ল্যাশ প্রক্রিয়াজাতকরণের আরও একটি স্তরকে প্রবর্তন করে) কখনও ব্যবহার $(...)না করে , পরিবর্তে ব্যবহার করুন।


¹ টেকনিক্যালি, echoএছাড়াও আর্গুমেন্ট হিসাবে পাস করা হয়েছে echoইউটিলিটি (এটা বলতে কিভাবে এটি চালানো হয়েছিল), এটা argv[0]এবং argc, যদিও অধিকাংশ শাঁস ইদানিং 3 echobuiltin হয়, তাই যে exec()একটি এর /bin/echo3 আর্গুমেন্ট একটি তালিকা সঙ্গে ফাইল দ্বারা কৃত্রিম হয় শেল। দ্বিতীয়টি ( argv[1]থেকে argv[argc - 1]) দিয়ে শুরু হওয়ার সাথে যুক্তিগুলির তালিকাটি বিবেচনা করাও সাধারণ কারণ কমান্ডগুলি মূলত তার উপর নির্ভর করে।

Free যে ja_JP.SJISফ্রিবিএসডি সিস্টেমগুলির চরসেটের কোনও চরিত্র \বা ~বৈশিষ্ট্য নেই তার হাস্যকর লোকাল হিসাবে এটি একটি উল্লেখযোগ্য ব্যতিক্রম !

³ মনে রাখবেন যে অনেকগুলি সিস্টেম (ফ্রিবিএসডি, সোলারিস, যদিও জিএনইউ নয়) [[:blank:]]ইউটিএফ -8 লোকেলগুলিতে ইউ + 00A0 কে একটি হিসাবে বিবেচনা করে, এই জাতীয় সমস্যা এড়াতে সম্ভবত আইএসও 8859-15 ব্যবহারকারীদের মতো অন্যান্য লোকেলগুলিতে কয়েকজনই করেন।


আপনার প্রথম অনুচ্ছেদে, আপনি আমাদের "... সেই 3 টি আর্গুমেন্টের চরিত্রগুলির মধ্যে ..." বলেছিলেন echo, আমি কেবল 2 টি আর্গুমেন্টকে কমান্ডের কাছে যাচ্ছি, আমি echoযে আর্গুমেন্টগুলি গণনা করতে পারি তা গণনা করি runএবং after_bundleআপনি কীভাবে ব্যাখ্যা করবেন যত্নশীল গণনা এবং 3 টি যুক্তি পেয়েছে?
ফেরিবিগ

1
@ ভিক্টরফোনিক, যুক্তির সংখ্যা সম্পর্কে সম্পাদনা দেখুন (এবং এটি যে মূল সমস্যাটি নয় echo)। দেখুন (exec -a foo /bin/echo --help)একটি গনুহ সিস্টেমে এবং কিভাবে একটি অবাধ প্রথম আর্গুমেন্ট পাস করার জন্য গনুহ শেল সঙ্গে /bin/echoইউটিলিটি।
স্টাফেন চেজেলাস

@ ফেরিবিগ স্টিফেনের সম্পাদনা দেখুন, পাদটীকা 1. সাধারণ সি স্টাইলে কমান্ড করার জন্য যুক্তিগুলি আর্গুমেন্টের অ্যারে হয়, আরজিভি [0] নিজেই এক্সিকিউটেবল নাম হিসাবে থাকে। $0শাঁসের মতো কিন্ডার মতো এবং অবস্থানগত পরামিতি।
সের্গেই কোলোডিয়াজনি

এখানে 373 টি এনকোডিং রয়েছে iconvযাতে এতে ESCরূপান্তরিত হয় '। চেষ্টা করুন (উদাহরণ হিসাবে):printf '\x1b'|iconv -f utf8 -t IBM-937|xxd
আইজ্যাক

এখানে 173 টি এনকোডিং রয়েছে যাতে কিছু কোডপয়েন্ট (ESC ব্যতীত) এ রূপান্তরিত হয় '। ব্যবহার করে দেখুন printf '\u2804' | iconv -f utf8 -t BRF | xxd। এমন এনকোডিং রয়েছে যার মধ্যে প্রচুর কোডপয়েন্ট রয়েছে '। ইউসিএস -4 এ প্রায় 8695 কোডপয়েন্ট হয়ে যায় '। ব্যবহার করে দেখুন printf '\U627' | iconv -cf utf-8 -t UCS-4। বেশ কয়েকটি (37) এনকোডিং 0x127 অক্ষরকে a তে রূপান্তর করে '। চেষ্টা করুনprintf '\U127' | iconv -cf utf8 -t UCS2 |xxd
আইজাক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.