কমান্ডের স্টিডিনে ভেরিয়েবলের মান কীভাবে প্রেরণ করা যায়?


105

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


আক্রমণকারী কি পরিবর্তন করতে পারে $PATH? যাতে catপ্রতিস্থাপন করা যায়/bin/cat "$@" | tee /attacker/can/read/this/file
12431234123412341234123

উত্তর:


74

এর মতো সাধারণ কিছু:

echo "$blah" | my_cmd

7
আপনার পরিবর্তনশীল জায়গায় স্পেস সাবধান: echo "$blah"ভাল।
জোনাথন লেফলার

13
দেখা যাক কিভাবে আপনি হ্যান্ডেল blah=-n, blah=-e... ব্যবহারের printfপরিবর্তে। unix.stackexchange.com/questions/65803/…
ক্যামিলো মার্টিন

1
এটি দেখে মনে হচ্ছে এটি ভঙ্গুর এবং ত্রুটি-প্রবণ হবে, না?
থারস্মমনার

19
6 বছর পরে, যদি আমি এই উত্তরটি মুছে ফেলতে পারি তবে আমি করব (তবে এটি গ্রহণযোগ্যতার কারণ আমি করতে পারি না ...)
অলিভার চার্লসওয়ার্থ

1
অলিভারচারসওয়ার্থ, এটি ব্যবহার করার জন্য কেন সম্পাদনা করবেন না printf '%s\n' "$blah"? যে এক পরিবর্তনের সাথে সাথে (অনেক ফাঁদ এড়ানো echoএর স্পেসিফিকেশন, যা স্টিফেন এর চমৎকার উত্তর এ বিস্তারিতভাবে মধ্যে যায় কেন printfবেশী ভালো echo? উপর ইউনিক্স ও লিনাক্স , বা যার অ্যাপ্লিকেশনের ব্যবহার অধ্যায় echoস্পেসিফিকেশন আরো সংক্ষেপে উপর ছোঁয়া) এটি একটি পুরোপুরি এর যুক্তিসঙ্গত উত্তর।
চার্লস ডাফি

192

একটি মান পাসিং stdinমধ্যে ব্যাশ হিসাবে সহজ হিসাবে:

your-command <<< "$your_variable"

সর্বদা নিশ্চিত হয়ে নিন যে আপনি পরিবর্তনশীল এক্সপ্রেশনগুলির চারপাশে উদ্ধৃতি স্থাপন করেছেন!

সাবধান থাকুন, এটি সম্ভবত কেবলমাত্র bashকাজ করবে এবং এতে কাজ করবে না sh


39
হেরেস্ট্রিংস <<<উপলব্ধ থাকার গ্যারান্টিযুক্ত নয়, তারা পসিক্স বেসে নেই, যতদূর আমি জানি। যতক্ষণ আপনি কেবল তাদের চালাচ্ছেন ততক্ষণ তারা প্রত্যাশা অনুযায়ী কাজ করবে bash। আমি কেবল এটি উল্লেখ করেছি, কারণ তারা ওপি বলেছিল 'শেল' বিশেষত 'বাশ' নয়। যদিও তিনি প্রশ্নটি ট্যাগটি দিয়েছিলেন bash... সুতরাং এটি এখনও স্পষ্টতই একটি গ্রহণযোগ্য উত্তর।
জেএম বেকার

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

@ স্টিভেনলু ওয়েট, echoএকটি অন্তর্নির্মিত। পাইপ নেই, তাই না? এটি ইউনিক্স, তবে এটি এতটা ইউনিক্স হতে পারে না ।
ক্যামিলো মার্টিন

4
@ স্টিভেনলু printf '%s\n' "$var"একই ফলাফল তৈরি করে echo "$var"তবে ভাঙবে না, উদাহরণস্বরূপ var=-en, এবং এমনকি বাশের প্রয়োজন নেই।
ক্যামিলো মার্টিন

1
এখানেও উল্লেখ করুন যে এখানে একটি স্ট্রিংয়ের জন্য একটি নতুন লাইন যুক্ত করা হয়েছে।
পিডিআর

19

নোট করুন যে ' echo "$var" | commandঅপারেশনগুলির অর্থ হ'ল স্ট্যান্ডার্ড ইনপুটটি প্রতিধ্বনিত রেখার মধ্যে সীমাবদ্ধ limited আপনি যদি টার্মিনালটি সংযুক্ত থাকতে চান তবে আপনাকে কল্পিত হতে হবে:

{ echo "$var"; cat - ; } | command

( echo "$var"; cat -   ) | command

এর অর্থ হ'ল প্রথম লাইনটি এর লিখিত বিষয়বস্তুতে থাকবে $varতবে বাকী অংশটি catএর স্ট্যান্ডার্ড ইনপুট পড়ার মাধ্যমে আসবে । কমান্ডটি যদি খুব অভিনব কিছু না করে (কমান্ড লাইন সম্পাদনা চালু করার চেষ্টা করুন বা এর মতো চালান vim) তবে তা ঠিক থাকবে। অন্যথায়, আপনি সত্যিই অভিনব হওয়া প্রয়োজন - আমি মনে করি expectবা এর ডেরাইভেটিভগুলির মধ্যে একটি উপযুক্ত হতে পারে।

কমান্ড লাইনের স্বরলিপিগুলি কার্যত অভিন্ন - তবে বন্ধনীগুলির সাথে না থাকলেও দ্বিতীয় আধা-কোলনটি বন্ধনীগুলির সাথে প্রয়োজনীয়।


( echo "$LIST"; cat - ) | sed 1qএটি আমার পক্ষে কাজ করে তবে আমি যখন এই স্ক্রিপ্টটি চালাচ্ছি তখন ctrl d টিপতে হবে?
গার্ট কুকেন্স

হ্যাঁ; cat -তাই আপনি টাইপিং নিয়ন্ত্রণ-D ফাইলের শেষে এটা বলতে চাই, ফাইলের শেষে বা বিঘ্ন পর্যন্ত কীবোর্ড থেকে পড়া চলতে।
জোনাথন লেফলার

ইওএফ এর চারপাশে কোন উপায় আছে?
সেডের

আপনি catযদি প্রথম লাইনের মতো টার্মিনাল ইনপুট না চান তবে আপনাকে কিছুটা ব্যবহার করতে হবে না। অথবা আপনি catএকটি ফাইল তালিকাবদ্ধ করতে ব্যবহার করতে পারেন । বা ... আপনি যদি কমান্ডটি টার্মিনাল ইনপুট পড়তে চান, আপনাকে ইনপুটটির শেষের দিকে পৌঁছে দিতে হবে। অথবা আপনি ব্যবহার করতে পারেন ( echo "$var"; sed /quit/q - ) | command; আপনি 'প্রস্থান' সমেত একটি লাইন টাইপ না করা অবধি এটি অবিরত থাকবে। আপনি কীভাবে এটি পরিচালনা করেন আপনি অন্তহীন উদ্ভাবক হতে পারেন। যখন ব্যবহারকারীরা ইকুয়েডরের সাথে কাজ শুরু করে তখন কাজ বন্ধ হয়ে যায় এমন কোনও প্রোগ্রামের পুরানো শহুরে কিংবদন্তি সম্পর্কে সাবধান হন। তারা রাজধানী, কুইটো নামে টাইপ করত এবং প্রোগ্রামটি বেরিয়ে আসে।
জোনাথন লেফলার

ঠিক আছে যদি আপনি বলেন। তবে শুধু কেন নয় echo "$LIST" | sed 1q | ...? এটি আপনার নির্ভরশীলতার উপর নির্ভর করে। <<EOFস্বরলিপি ফাইল নিচে নিজস্ব কোথাও উপর একটি লাইন শুরুতে একটি ফাইলের শেষে প্রয়োজন করা উচিত নয়। আমি এটি ব্যবহার করব না, আমি মনে করি - তবে আপনি কী অর্জন করতে চাইছেন তা এখনও নিশ্চিত নই। একটি সাধারণ echo "$LIST" | commandবা echo $LIST | commandসম্ভবত অভ্যাসে যথেষ্ট হবে (এবং এটি গুরুত্বপূর্ণ যে আপনি উভয়ের মধ্যে পার্থক্যের তাত্পর্যটি জানেন)।
জোনাথন লেফলার

16

আমি মার্টিনের উত্তর পছন্দ করেছি, তবে ভেরিয়েবলটি কী তার উপর নির্ভর করে এতে কিছু সমস্যা আছে। এই

your-command <<< """$your_variable"""

যদি আপনি ভেরিয়েবল "বা!


4
কিন্তু কেন? এছাড়াও, আমি কোনও সমস্যা পুনরুত্পাদন করতে পারি না: foo1=-; foo2='"'; foo3=\!; cat<<<"$foo1"; cat<<<"$foo2"; cat<<<"$foo3"আমার পক্ষে কাজ করে। তিনজন ঠিক কী করে "? আফাইক আপনি খালি স্ট্রিংটি কেবলমাত্র সরবরাহ এবং সংযোজন করছেন।
পিএইচকে

বাস্তব কিছু চেষ্টা করুন। আপনার কমান্ড যেমন কোনওভাবে ssh। এবং আপনার পরিবর্তনশীল একটি শেল স্ক্রিপ্ট।
রবার্ট জ্যাকবস

16
(cat <<END
$passwd
END
) | command

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


তবে এই পদ্ধতিটি আপনাকে আপনার কমান্ডে একাধিক লাইনগুলি অতিক্রম করার অনুমতি দেয় এবং$passwd
পোল্টোস

4
এটি এখন পর্যন্ত সেরা উত্তর যা পাইপ বা স্নুপিং প্রক্রিয়াতে পরিবর্তনশীল সামগ্রীগুলি ফাঁস করে না।
ব্যবহারকারী2688272

8

মার্টিনের উত্তর অনুসারে, হিয়ার স্ট্রিংস নামে একটি বাশ বৈশিষ্ট্য রয়েছে (এটি নিজেই বহুলাংশে সমর্থিত হিয়ার ডকুমেন্টস বৈশিষ্ট্যের একটি রূপ )।

http://www.gnu.org/software/bash/manual/bashref.html#Here-Strings

3.6.7 এখানে স্ট্রিংস

এখানে নথির একটি বৈকল্পিক, ফর্ম্যাটটি হ'ল:

<<< word

শব্দটি প্রমিত করা হয় এবং এর স্ট্যান্ডার্ড ইনপুটটিতে কমান্ড সরবরাহ করা হয়।

নোট করুন যে এখানে স্ট্রিংগুলি কেবলমাত্র ব্যাশ হিসাবে উপস্থিত হবে, সুতরাং উন্নত পোর্টেবিলিটির জন্য, পল্টোসের উত্তর অনুসারে আপনি সম্ভবত এখানে মূল নথির বৈশিষ্ট্যটি দিয়ে আরও ভাল হতে পারবেন:

( cat <<EOF
$variable
EOF
) | cmd

বা, উপরের একটি সহজ বৈকল্পিক:

(cmd <<EOF
$variable
EOF
)

আপনি বাদ দিতে পারেন (এবং ), যদি না আপনি এটি অন্য কমান্ডের দিকে আরও পুনঃনির্দেশিত করতে চান।


5

এই শক্তিশালী এবং পোর্টেবল উপায় ইতিমধ্যে মন্তব্যে হাজির হয়েছে। এটি একক উত্তর হওয়া উচিত।

printf '%s' "$var" | my_cmd

অথবা

printf '%s\n' "$var" | my_cmd

মন্তব্য:

  • এটি এর চেয়ে ভাল echo, কারণগুলি এখানে রয়েছে: এর চেয়ে ভাল কেন ?printfecho
  • printf "$var"ভূল. প্রথম আর্গুমেন্ট বিন্যাস যেখানে বিভিন্ন সিকোয়েন্স পছন্দ করেন %sবা \nকরছেন ব্যাখ্যা । ভেরিয়েবলটি সঠিকভাবে পাস করতে, এটি ফর্ম্যাট হিসাবে ব্যাখ্যা করা উচিত নয়।
  • সাধারণত ভেরিয়েবলগুলিতে ট্রেলিং নিউলাইন থাকে না। প্রাক্তন কমান্ড (সহ %s) ভেরিয়েবলটি যেমনটি পাস করে ততক্ষণে। তবে পাঠ্য নিয়ে কাজ করা সরঞ্জামগুলি অপূর্ণ লাইন সম্পর্কে উপেক্ষা বা অভিযোগ করতে পারে (দেখুন কেন পাঠ্য ফাইলগুলি একটি নতুন লাইনের সাথে শেষ করা উচিত? )। সুতরাং আপনি পরবর্তী কমান্ডটি (এর সাথে %s\n) চাইবেন যা ভেরিয়েবলের সামগ্রীতে একটি নতুন লাইন চরিত্র যুক্ত করে। অস্পষ্ট তথ্য:

    • এখানে বাশ ( <<<"$var" my_cmd) এর স্ট্রিং একটি নতুন লাইন যুক্ত করে।
    • my_cmdভেরিয়েবলটি খালি বা অপরিজ্ঞাত থাকলেও যে কোনও পদ্ধতিতে একটি নতুন লাইনের ফলাফল যুক্ত হয় না তা খালি স্টিডিনের ফলাফল ।

4

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

echo "$variable" | command

তবে বিষয়গুলি $ পরিবর্তনশীল প্রদর্শিত হবে না যেমন ps -uপ্রতিধ্বনি যখন চলছে তখন কি ফলাফল হয়?

2
না এটা হবে না। echoএকটি অন্তর্নির্মিত, তাই পিএস
আনবেলি

2
আপনার পরিবর্তনশীল জায়গায় স্পেস সাবধান: echo "$variable"ভাল।
জোনাথন লেফলার

এটা ঠিক, বাশ দ্বিগুণ স্থান খাবে, স্মার্ট
শেলসটি খাবে

-1

শুধু কর:

printf "$my_var" | my_cmd

ভারে যদি স্পেস না থাকে তবে উদ্ধৃতিগুলি বাদ দেওয়া যেতে পারে।
যদি ব্যাশ ব্যবহার করে থাকেন তবে আপনি এটিও করতে পারেন:

echo -n "$my_var" | my_cmd

-N ছাড়া ইকো ব্যবহার করা এড়িয়ে চলুন কারণ এটি শেষে যুক্ত হওয়া লাইনব্রেকের সাথে ভ্রিয়েবলকে পাইপ করবে।


1
$ my_var হয় %s, প্রিন্টফ কিছু প্রিন্ট করবে না যদি কাজ করে না । my_var="%s"; printf "$my_var"; - হয়তো চেষ্টা কর printf "%s" "$my_var" | my_cmd ?
hanshenrik
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.