ব্যাশে বৈধ কমান্ডের আগে ভেরিয়েবল সেট করা কেন?


68

আমি শুধু এই ধরনের হিসাবে বিভিন্ন উত্তর সম্মুখীন হয়েছি একটি সীমায়িত টেক্সট ফাইল ... পার্স যে কনস্ট্রাক্ট ব্যবহার করুন:

while IFS=, read xx yy zz;do
    echo $xx $yy $zz
done < input_file

যেখানে IFSভেরিয়েবল readকমান্ডের আগে সেট করা আছে ।

আমি বাশ রেফারেন্স দিয়ে পড়ছি তবে কেন এটি আইনী তা বুঝতে পারি না।

আমি চেষ্টা করেছিলাম

$ x="once upon" y="a time" echo $x $y

bash কমান্ড প্রম্পট থেকে কিন্তু কিছুই প্রতিধ্বনিত হয়নি। কেউ কি আমাকে নির্দেশ করতে পারেন যেখানে সেই সিনট্যাক্সটি এমন রেফারেন্সে সংজ্ঞায়িত করা হয়েছে যা আইএফএস ভেরিয়েবলটিকে সেভাবে সেট করার অনুমতি দেয়? এটি কি বিশেষ ক্ষেত্রে বা আমি অনুরূপ ডাব্লু / অন্যান্য ভেরিয়েবলগুলি করতে পারি?


উত্তর:


69

এটি শেল ব্যাকরণের অধীনে, সরল কমান্ড (জোর দেওয়া):

একটি সাধারণ কমান্ড হ'ল alচ্ছিক পরিবর্তনশীল অ্যাসাইনমেন্টগুলির ক্রম যা পরে ফাঁকা-বিচ্ছিন্ন শব্দ এবং পুনঃনির্দেশগুলি এবং একটি নিয়ন্ত্রণ অপারেটর দ্বারা সমাপ্ত ated প্রথম শব্দ কমান্ড নিষ্পন্ন করা হবে নির্দিষ্ট করে, এবং যুক্তি শূন্য হিসাবে পাস করা হয়েছে। বাকি শব্দগুলি চালিত কমান্ডের যুক্তি হিসাবে পাস করা হয়।

সুতরাং আপনি চান যে কোনও ভেরিয়েবল পাস করতে পারেন। আপনার echoউদাহরণটি কাজ করে না কারণ ভেরিয়েবলগুলি কমান্ডের কাছে সরিয়ে দেওয়া হয়েছে, শেলটিতে সেট করা হয়নি। শেল প্রসারিত হয় $xএবং কমান্ড চাওয়ার $y আগে । এটি কাজ করে, উদাহরণস্বরূপ:

$ x="once upon" y="a time" bash -c 'echo $x $y'
once upon a time

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

1
হুম আমি মনে করি আমাকে আরও ভাল রেফারেন্সের সন্ধান করতে হবে, আমার (উপরের লিঙ্কটি দেখুন) এটিতে শেল ব্যাকরণ বিভাগ নেই বলে দেয় না।
মাইক লিপার্ট

1
@ মাইকলিপার্ট that. ..৪ দেখুন সেই রেফারেন্সে ("কোনও সাধারণ কমান্ড বা ফাংশনের পরিবেশকে সাময়িকভাবে প্যারামিটার অ্যাসাইনমেন্ট সহ উপস্থাপনের মাধ্যমে বাড়ানো যেতে পারে")। আমি মনে করি যে উল্লেখটি বাশের একটি পুরানো সংস্করণ থেকে এসেছে। আমি কেবল man bashআমার সিস্টেমে
দৌড়েছি

29

সংজ্ঞায়িত ভেরিয়েবলগুলি কাঁটাচামচ প্রক্রিয়াতে পরিবেশের ভেরিয়েবলের মতো হয়ে যায়।

আপনি যদি চালান

A="b" echo $A

তারপরে ব্যাশ প্রথমে প্রসারিত $Aহয় ""এবং তারপরে রান করে

A="b" echo

এখানে সঠিক উপায়:

x="once upon" y="a time" bash -c 'echo $x $y'

একক উদ্ধৃতি লক্ষ্য করুন bash -c, অন্যথায় আপনার উপরের মতো একই সমস্যা রয়েছে।

সুতরাং আপনার লুপ উদাহরণটি বৈধ কারণ ব্যাশ বিল্টিন 'রিড' কমান্ড তার পরিবেশের ভেরিয়েবলগুলিতে আইএফএসের সন্ধান করবে এবং এটি সন্ধান করবে ,। অতএব,

for i in `TEST=test bash -c 'echo $TEST'`
do
  echo "TEST is $TEST and I is $i"
done

মুদ্রণ করবে TEST is and I is test

শেষ অবধি সিনট্যাক্সের ক্ষেত্রে লুপের জন্য একটি স্ট্রিং আশা করা যায়। সুতরাং এটি কমান্ড তৈরি করতে আমাকে ব্যাকটিক্স ব্যবহার করতে হয়েছিল। তবে লুপগুলি কমান্ড সিনট্যাক্সের যেমন প্রত্যাশা করে IFS=, read xx yy zz


1
ধন্যবাদ, আমি আপনার উত্তর জিজ্ঞাসা চেয়ে একটু বেশি শিখেছি। আমি আপনার উত্তরটিও ভোগ করব, তবে এখনও আমার অনুমতি নেই এবং আমি প্রথম উত্তরটিতে গৃহীত উত্তরটিকে পতাকাঙ্কিত করেছি।
মাইক লিপার্ট

1
ধন্যবাদ, আমি এটাই প্রত্যাশা করছিলাম। এবং একটি ভোট আপ আপনার প্রশংসা শুনে কম অর্থবহ!
মাইক ফেয়ারহર્স্ট

কোডের প্রথম লাইনের অধীনে আপনার মন্তব্যটি স্পষ্ট করতে: হ্যাঁ, আনসেট Aভেরিয়েবল ব্যাশটি $Aফাঁকা স্ট্রিংয়ের সাথে প্রসারিত হয় তবে বিভ্রান্তি এড়াতে আমি ব্যবহার করব না ""কারণ কোডটির সমতুল্য নয় A="b" echo ""। এ নিয়ে কোনও যুক্তি থাকবে না echo
পাবউক

8

man bash

পরিবেশ

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

ভেরিয়েবল অ্যাসাইনমেন্ট হওয়ার আগে ভেরিয়েবলগুলি প্রসারিত হয়। সুস্পষ্ট কারণে যা var=xঅন্যভাবে কাজ করবে, কিন্তু var=$othervarতা করবে না। অর্থাৎ $xএটি উপলব্ধ হওয়ার আগে আপনার প্রয়োজন। তবে এটিই মূল সমস্যা নয়। মূল সমস্যাটি হ'ল কমান্ড লাইনটি কেবল শেল এনভায়রনমেন্ট দ্বারা পরিবর্তন করা যেতে পারে তবে অ্যাসাইনমেন্টটি শেল পরিবেশের অংশ হয় না of

আপনি বৈশিষ্ট্যগুলিতে মিশ্রিত হন: আপনি একটি কমান্ড লাইন প্রতিস্থাপন করতে চান তবে পরিবর্তনশীল সংজ্ঞাটি কমান্ড পরিবেশে রাখুন। শেল দ্বারা কমান্ড লাইন প্রতিস্থাপন করতে হবে। পরিবেশ অবশ্যই স্পষ্টভাবে ব্যবহৃত কমান্ড দ্বারা ব্যবহার করা উচিত। এটি কীভাবে এবং কীভাবে করা হয় তা কমান্ডের উপর নির্ভর করে।

এই ব্যবহারের সুবিধা হ'ল আপনি শেল পরিবেশকে প্রভাবিত না করে একটি উপ-প্রসেসের জন্য পরিবেশ নির্ধারণ করতে পারেন।

x="once upon" y="a time" bash -c 'echo $x $y'

আপনি যেমন প্রত্যাশা করেন তেমন কাজ করে কারণ সে ক্ষেত্রে উভয় বৈশিষ্ট্যই একত্রিত হয়: কমান্ড লাইন প্রতিস্থাপনটি কলিং শেল দ্বারা নয় তবে সাবপ্রসেস শেল দ্বারা সম্পন্ন হয়।


1
এটি তার চেয়ে x="once upon" y="a time" eval 'echo $x $y'খানিকটা সূক্ষ্ম, কারণ evalএকটি বিল্টিন থাকার কারণে কোনও সাবপ্রসেস জড়িত না থাকলে উদাহরণটিও কাজ করে । ম্যানপেজ থেকে প্রাসঙ্গিক উক্তিটি অনুমান করি The environment for any simple command or function may be augmented temporarily by prefixing it with parameter assignments। প্রশ্নের উদাহরণ বিবেচনা করে এটি এইভাবে হতে হবে যেহেতু readএটিও একটি বিল্টিন এবং এটি সাময়িকভাবে পরিবর্তিত রাষ্ট্রের সাথে কাজ করে IFS
ডেভিড ওঙ্গারো

4

কমান্ড প্রদান কারণ ভিন্ন $xএবং $yপ্রসারিত হয় আগেecho কমান্ড রান, তাই তাদের মান বর্তমান শেল ব্যবহার করা হয়, না মান যে echoতার পরিবেশের দেখতে হবে যদি এটি দেখুন ছিলেন।


কমান্ড চলার পরে কমান্ড লাইনের কিছু বাড়ানো যায় কীভাবে ...?
হউক লেগেছে 17

প্রাক-কমান্ড বরাদ্দকরণ করতে xএবং yপরিবেশের জন্য echoযা করা আর্গুমেন্ট পরিবেশ না চালায়, echoপ্রসারিত করছে। কারণ IFS=, read xx yy zz, সম্পূর্ণ স্ট্রিংটি readকমান্ড দ্বারা পঠিত, আনস্প্লিট করা হয় । তারপর , যে স্ট্রিং এর মান অনুযায়ী বিভক্ত করা IFS, নির্ধারিত সংশ্লিষ্ট টুকরা সঙ্গে xx, yyএবং zz
চিপনার

আমি কেবল এটি উল্লেখ করতে চেয়েছিলাম যে "কমান্ড চালুর আগেই প্রসারিত" শব্দটির কোনও অর্থ হয় না কারণ কমান্ড শুরুর পরে আর কিছুই আর প্রসারিত হয় না। তদ্ব্যতীত: আমার উত্তর সম্পর্কে আপনার কি এক নজর ছিল না বা তবুও আপনি কি বিশ্বাস করেন যে আমার কি হচ্ছে তার ব্যাখ্যা দরকার? ...
হউক লেগেছে

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

echoআমার ক্ষেত্রে এটি নিশ্চিত ছিল না যে এটি পরিবর্তনশীলটি "দেখতে" পারে কিনা, কারণ এটি একটি বিল্টিন কমান্ড এবং অতএব কোনও সাব-শেল চালায় না যার নিজস্ব পরিবেশ থাকতে পারে। তবে আমি এটি চেষ্টা করেছিলাম evalযা একটি বিল্টিন এবং এটি সত্যই এটি সম্পর্কে জানে। উদাহরণস্বরূপ চেষ্টা করুন a=xyz eval 'echo $BASHPID $a; grep -z ^a /proc/$BASHPID/{,task/*}/environ'; echo $BASHPID $aযা দেখায় যে aকেবলমাত্র সেট করা আছে evalযদিও পিড একই এবং পরিবেশের সময় পরিবেশ পরিবর্তিত হয় না! (অ্যাক্সেস করার জন্য /procআপনাকে এটি লিনাক্সের অধীনে চালানো দরকার)) মনে হচ্ছে বাশ এখানে কিছু অতিরিক্ত যাদু করে।
ডেভিড ওঙ্গারো

2

আমি " এটি আইনানুগ কেন " এর বড় ছবিতে যাচ্ছি

উত্তর: যাতে আপনি কোনও প্রোগ্রামকে কল করতে বা ডাকতে পারেন এবং সেই আহ্বানের জন্য কেবল একটি নির্দিষ্ট ভেরিয়েবলের সাথে একটি ভেরিয়েবল ব্যবহার করতে পারেন।

উদাহরণ হিসাবে: আপনার কাছে 'db_connection' নামক একটি ডাটাবেস সংযোগের জন্য একটি প্যারাম রয়েছে এবং সাধারণত আপনি পরীক্ষার ডাটাবেস সংযোগের নাম হিসাবে 'পরীক্ষায়' পাস করেন। বাস্তবে আপনি এটিকে ডিফল্ট হিসাবে সেটও করতে পারেন যা আপনাকে পরে স্পষ্টভাবে পাস করার দরকার নেই। কখনও কখনও আপনি সিআই ডাটাবেস সঙ্গে কাজ করতে চান। সুতরাং আপনি 'সিআই' হিসাবে পরম পাস এবং তারপরে প্রোগ্রাম বলা হচ্ছে যে ডাটাবেস প্যারাম ব্যবহার করে সমস্ত ডাটাবেস কল জন্য db নাম হিসাবে। পরবর্তী রানের জন্য, আপনি যদি পদ্ধতির পুনরাবৃত্তি না করে এবং প্রোগ্রামটিকে কেবল কল করেন না তবে ভেরিয়েবলটি তার পূর্ববর্তী ডিফল্ট মানটিতে ফিরে আসবে।


0

আপনি ব্যবহার করতে পারেন ;। এটি পূর্বে মূল্যায়ন করা হবে কারণ এটি কমান্ড বিভাজক।

x="once upon" y="a time"; echo $x $y

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