একটি ভেরিয়েবলে সঞ্চিত কমান্ড কার্যকর করুন


11

আমার একটি কমান্ড ভেরিয়েবলে সঞ্চিত আছে। ভেরিয়েবলের $iমান রয়েছে তা ভান করা যাক :

cat -nT index.php |grep 'someregex'

যখন আমি উপরের ভেরিয়েবলটি টাইপ করে $iএটি প্রয়োগ করে ব্যর্থ হই কারণ শেল পুরো ভেরিয়েবলটিকে একটি কমান্ড হিসাবে কার্যকর করার চেষ্টা করে। আমি ব্যাকটিক্স ব্যবহার eval($i)এবং রাখার চেষ্টা করেছি $i

আমি শেলটিকে কীভাবে $iএকটি আদেশ হিসাবে চালিত করতে পারি ? এবং কেন এটি একইভাবে কাজ করছে না।

$i='echo hi'; $i

এটি কি কারণ একক উদ্ধৃতিগুলিতে আমাকে হ্যাক করতে হয়েছিল? (কারণ আপনি এগুলি বাসাতে পারেন না)) বর্তমানে আমার সমাধানটি

echo $i > /foo;  . /foo

তবে আমি এটির জন্য কোনও ফাইল তৈরি করতে চাই না, কেবল এটি পরে মুছে ফেলতে চাই।

"আমি একক উক্তি হ্যাক করেছি এর দ্বারা আমি কী বোঝাতে চাইছি তা হল:

$i='cat index.php | grep -P '"'"'MYREGEXHERE'"'"

4
প্রশ্নটি হ'ল কেন কমান্ডটি প্রথম স্থানে একটি ভেরিয়েবলে সংরক্ষণ করা হয়? আপনি যখন কমান্ডটি চালাবেন তখন ভেরিয়েবল বা অ্যারেতে বিকল্প আর্গুমেন্টগুলি সংরক্ষণ করে রাখলে আপনি আরও ভাল। আপনার কাছে থাকা পুরো স্ক্রিপ্টটি কি আপনি দেখাতে পারবেন?
slhck

উত্তর:


18

সংক্ষিপ্ত উত্তর: বাশাক # 50 দেখুন: আমি একটি ভেরিয়েবলে একটি কমান্ড দেওয়ার চেষ্টা করছি, তবে জটিল ক্ষেত্রে সবসময় ব্যর্থ হয়!

দীর্ঘ উত্তর: এটি সেই আদেশের কারণেই যা বাশ কমান্ড লাইনটিকে পার্স করে। বিশেষত, এটি পাইপ এবং পুনঃনির্দেশগুলির মতো জিনিসগুলি ভেরিয়েবল মানগুলি প্রসারণ করার আগে সন্ধান করে এবং প্রসারিত মানগুলিতে পাইপ ইত্যাদির জন্য ফিরে যায় না এবং পুনরায় সন্ধান করে না। মূলত, ভ্যারিয়েবলগুলি পার্সিং প্রক্রিয়াটির প্রায় অর্ধেকের পরিবর্তে প্রতিস্থাপিত হয়, সুতরাং মান কার্যকর হওয়ার আগে কেবল অর্ধেক অংশকে পার্স করা হয়।

এটি সমাধান করার জন্য, আপনাকে @ স্লহ্যাকের প্রশ্নের উত্তর দিতে হবে: কমান্ডটি কেন প্রথম স্থানে একটি ভেরিয়েবলে সংরক্ষণ করা হয়? আপনি যে আসল সমস্যাটি সমাধান করার চেষ্টা করছেন তা কী? আসল লক্ষের উপর নির্ভর করে সম্ভাব্য কয়েকটি সমাধান রয়েছে:

  • এটিকে কোনও ভেরিয়েবলে সংরক্ষণ করবেন না, কেবল এটি সরাসরি চালিত করুন। পরবর্তী ব্যবহারের জন্য কমান্ডগুলি সংরক্ষণ করা জটিল এবং আপনার যদি সত্যিই প্রয়োজন না হয় তবে ঠিক করবেন না।

  • ভেরিয়েবলের পরিবর্তে একটি ফাংশন ব্যবহার করুন। সর্বোপরি তারা এর জন্য:

    i() { cat -nT index.php |grep 'someregex'; }
    i
    

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

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

    i="cat -nT index.php |grep 'someregex'"
    eval "$i"
    

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


evalপদ্ধতির জন্য +1 । এটি আমাকে একই প্রশ্ন জিজ্ঞাসা করা থেকে বিরত করেছে :)। আমার এমন কিছু আছে যা sudo rsync -aAHXi -n --delete-excluded --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/lost+found","/mnt/DATA/*","/var/log/*","/var/swap","/var/cache/apt/archives/*.deb"} -e ssh root@piac_wireless:/ /home/mrx/Docs/RPi/backup/piac/piac_usb-rootব্যতিক্রমগুলি সঠিকভাবে সম্পাদন করছে না।
dentex

@ এডেনটেক্স আমি এটির evalজন্য ব্যবহারের বিরুদ্ধে দৃ strongly়ভাবে সুপারিশ করব - এর ভুল হওয়ার অনেকগুলি উপায় রয়েছে। একটি অ্যারে এটি করার আরও ভাল উপায় হবে। উদাহরণস্বরূপ এখানে , এখানে এবং এখানে দেখুন ।
গর্ডন ডেভিসন

পরামর্শের জন্য ধন্যবাদ. ব্যয় তালিকাটি আরএসসিএন-তে পাস করার জন্য আমি অ্যারের সাথে সমাধানটি প্রয়োগ করার চেষ্টা করব।
dentex

4

এটি কেবল কাজ করা উচিত:

a="cat -nT index.php |grep 'someregex'"
eval "$a"

সতর্ক থাকুন যে evalপ্রবর্তন সম্ভাব্য দুর্বলতা এবং অপ্রত্যাশিত আচরণের পরিস্থিতিতে তাই হয়, ব্যবহার করা আবশ্যক যদি কখনও, অতিরিক্ত যত্নের সাথে।


আপনি যদি ব্যবহার করেন তবে অতিরিক্ত-অদ্ভুত প্রভাব এড়াতে evalআপনাকে সত্যই ডাবল-কোট ( eval "$i") ব্যবহার করতে হবে। উদাহরণস্বরূপ, a="cat -nT index.php |grep ' .* '"এটির সাহায্যে চেষ্টা করুন (অর্থাত্ রেজেক্সের মধ্যে দুটি বর্ণের ক্রমের সাথে দুটি স্পেসের মিল থাকা উচিত) এবং দেখুন কী ঘটে। অতিরিক্ত creditণের জন্য, কেন এটি ঘটে তা ব্যাখ্যা করুন ।
গর্ডন ডেভিসন

@ গর্ডন ডেভিসন ডাবল উদ্ধৃতি যোগ করা হয়েছে।
jlliagre

2

ভেরিয়েবল ঘোষণা করার সময়, আপনার ডলার চিহ্নটি উপসর্গ হিসাবে ব্যবহার করা উচিত নয়।

এটা চেষ্টা কর:

i='echo hi'; $i

1
এটি সঠিক, তবে এটি আসলে ওপি-র প্রশ্নের উত্তর নয়।
9-29 এ ছোঁয়া

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