কেন "A = 10 প্রতিধ্বনি $ এ" 10 মুদ্রণ করে না?


25

এই আদেশ:

A=10 echo $A

একটি খালি লাইন মুদ্রণ। কেন হবে না 10? কেন স্থানটিতে অস্থায়ী পরিবেশ সেটিং কাজ করে না?

আমি সমাধানের চেয়ে কারণ এবং ব্যাখ্যা জানতে চাই।

আমি ব্যবহার করতাম

LANG=C gcc ...

জিসিিকে সিস্টেম ল্যাঙ্গুয়েজ (চাইনিজ) এর পরিবর্তে ফ্যালব্যাক ভাষা (ইংরেজি) ব্যবহার করতে বাধ্য করতে। সুতরাং আমি অনুমান করি একটি VAR=valueউপসর্গ এটি অনুসরণ করে কমান্ডের জন্য একটি অস্থায়ী পরিবেশ স্থাপন করবে। তবে দেখে মনে হচ্ছে আমার কিছু ভুল ধারণা রয়েছে।

উত্তর:


22

এটি আদেশের বিষয় যেখানে কোনও আদেশের মূল্যায়নের বিভিন্ন ধাপ ঘটে।

A=10 echo $Aপ্রথম পার্স একটি সহজ কমান্ড মধ্যে কমান্ড তিনটি শব্দের তৈরি A=10, echoএবং $A। তারপরে প্রতিটি শব্দের পরিবর্তনশীল প্রতিস্থাপন হয়, অর্থাত্ $Aতাদের মানগুলিতে যেমন পরিবর্তনশীল বিস্তারের রূপান্তর (আমি কিছুই না দেখায় এমন পদক্ষেপগুলি বাদ দিচ্ছি)।

যদি Aমূল্য আছে fooপ্রথমে সম্প্রসারণ ধাপের ফলাফলের একটি সহজ কমান্ড এখনো তিন শব্দ আছে যা হল: A=10, echoএবং foo। (শেলটি এই মুহুর্তে মনে রাখে যে অক্ষরগুলি প্রথমে উদ্ধৃতিগুলির মধ্যে ছিল - এই ক্ষেত্রে কোনও কিছুই নয়)) পরবর্তী পদক্ষেপটি হ'ল কমান্ডটি কার্যকর করা। যেহেতু A=10একটি বৈধ ভেরিয়েবল নামের সাথে সমান চিহ্ন দ্বারা শুরু হয়, তাই এটি একটি নিয়োগ হিসাবে বিবেচিত হয়; কমান্ডটি কার্যকর করার সময় শেল এবং পরিবেশ উভয় ক্ষেত্রে ভেরিয়েবল Aসেট করা 10হয়। (সাধারণত আপনাকে শেল ভেরিয়েবল হিসাবে নয়, পরিবেশে লিখতে export Aহবে A; এটি একটি ব্যতিক্রম)) পরবর্তী শব্দটি কোনও অ্যাসাইনমেন্ট নয়, সুতরাং এটি কমান্ডের নাম হিসাবে বিবেচিত হয় (এটি একটি বিল্ট-ইন কমান্ড)। দ্যechoকমান্ড কোনও ভেরিয়েবলের উপর নির্ভর করে না, A=10 echo $Aঠিক তেমন একই প্রভাব রয়েছে echo $A

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

(A=10; echo $A)

আপনি export A=10যদি পরিবেশে পরিবর্তনশীল রফতানি করতে চান তা তৈরি করুন যাতে এটি বাহ্যিক প্রোগ্রামগুলির দ্বারা দেখা যায়।


ধন্যবাদ, আমি কি বলতে পারি A=10 (echo $A)এবং পেতে 10পারি?
আর্থ ইঞ্জিন

2
@ আর্থ আর্থিন না, এটি একটি সিনট্যাক্স ত্রুটি হবে। অ্যাসাইনমেন্টটি একটি সরল কমান্ডের (যেমন একটি কমান্ডের নাম এবং কিছু প্যারামিটার এবং বিকল্পভাবে কিছু প্রাথমিক অ্যাসাইনমেন্ট এবং কিছু পুনর্নির্দেশ) শুরুতে হবে। A=10; (echo $A)আউটপুট 10কিন্তু Aস্ক্রিপ্ট বাকি জন্য সেট ।
গিলস 'অশুভ হওয়া বন্ধ করুন'

2
@ আর্থ আর্থাইন তবে আপনি বলতে পারেন A=10 eval 'echo $A'$Aপুরো লাইনটি মূল্যায়ন না করা পর্যন্ত একক-উদ্ধৃতিগুলি ব্যাখ্যা করা বন্ধ করুন ... কোন সময়ের মধ্যে এ = 10। আমি এই উত্তর গ্রহণযোগ্য চেয়ে বেশি অধিকার বিবেচনা করি ।
অলি

আমি মনে করি এটি সঠিক ব্যাখ্যা। আচরণের কারণটি হ'ল ক্রমটি যখন সম্প্রসারণ $Aএবং এর কার্যভার নির্ধারণের ক্রম Aহয়। উদাহরণস্বরূপ, A=5; A=6 let 'a=A'; echo $aফেরত আসে 6না 5এবং আমি মনে করি না যে letএটি একটি সাব-সেল শুরু করে, যেহেতু এটি একটি বিল্টিন কমান্ড।
ডেভিড ওঙ্গারো

@EarthEngine: যখন এটা বলা হয়ে থাকে যে সঠিক ব্যাখ্যা অর্ডার মূল্যায়ন, এটা বিভ্রান্তিকর হতে পারে: A=10 echo $Aহবে না সেট A=10পরে কোন কমান্ডের জন্য, এমনকি যদি তারা বিভিন্ন লাইন (যখন পরিষ্কারভাবে নিয়োগ হয় ছিল ইতিমধ্যে মূল্যায়ন)। এটি অর্ডার সম্পর্কে নয়, এটি সুযোগ
MestreLion

37

যখন আপনি ব্যবহার LANG=C gcc ... সেখানে কি ঘটছে যে শেল জন্য সেট করে LANG- তে হয় gccএর পরিবেশ শুধুমাত্র , এবং না জন্য বর্তমান পরিবেশ নিজেই ( নোট দেখুন )। সুতরাং gccশেষ হওয়ার পরে , LANGতার আগের মানটিতে ফিরে আসে (বা আনসেট না করা)।

তদ্ব্যতীত, আপনি যখন A=10 echo $Aএটি ব্যবহার করেন তখন শেল যা প্রতিধ্বনি নয়, $ A প্রতিস্থাপন করে, এবং এই বিকল্পটি ("এক্সপেনশন" নামে পরিচিত) বিবৃতিটি মূল্যায়ন করার আগে ঘটে (অ্যাসাইনমেন্ট সহ), সুতরাং প্রত্যাশার Aমান হিসাবে ইতিমধ্যে সেট করা থাকতে হবে মধ্যে বর্তমান যে বিবৃতি পূর্বে পরিবেশ।

এ কারণেই A=10 echo $Aপ্রত্যাশার মতো কাজ করে না: A=10প্রতিধ্বনির জন্য সেট করা হবে তবে পরিবেশগত ভেরিয়েবলের মান ইকো অভ্যন্তরীণভাবে উপেক্ষা করবে A। এবং বর্তমান শেলটিতে$A মান সেট (যা কোনটি নয়) দ্বারা প্রতিস্থাপিত হয় এবং এর পরে প্রতিধ্বনি হিসাবে যুক্ত হয়ে যায়।

সুতরাং আপনার অনুমানটি সঠিক: কাজ VAR=value command করে তবে এটি কেবলমাত্র প্রাসঙ্গিকভাবে যদি commandঅভ্যন্তরীণভাবে VAR ব্যবহার করে । যদি তা না হয়, আপনি কি এখনও পাস করতে পারেন valueএকটি যেমন যুক্তি করার command, কিন্তু যুক্তির দ্বারা প্রতিস্থাপিত হয় বর্তমান , শেল তাই তারা ব্যবহার করার পূর্বে নির্ধারণ করা আবশ্যক:VAR=value; command "$VAR"

যদি আপনি কীভাবে এক্সিকিউটেবল স্ক্রিপ্ট তৈরি করতে জানেন তবে আপনি এটি পরীক্ষা হিসাবে চেষ্টা করতে পারেন:

#!/bin/sh
echo "1st argument is $1"
echo "A is $A"

এটি হিসাবে সংরক্ষণ করুন testscriptএবং চেষ্টা করুন:

$ A=5; A=10 testscript "$A"; echo "$A"
1st argument is 5
A is 10
5

সর্বশেষে তবে সর্বনিম্ন নয়, শেল এবং পরিবেশের ভেরিয়েবল এবং প্রোগ্রাম আর্গুমেন্টের মধ্যে পার্থক্যটি জানা ভাল ।

এখানে কিছু ভাল উল্লেখ রয়েছে:

(*) নোট: টেকনিক্যালি শেল নেই খুব বর্তমান পরিবেশে সেট, এবং এখানে কেন: কিছু কমান্ড, মত echo, readএবং testহয় শেল builtins , এবং যেমন তারা একটি শিশু প্রক্রিয়া ডিম না। তারা বর্তমান পরিবেশে চালানো। কমান্ডটি চালা না হওয়া পর্যন্ত শেলটি কেবলমাত্র অ্যাসাইনমেন্টের যত্ন নেয় so সুতরাং সমস্ত ব্যবহারিক কাজের জন্য প্রভাব একই হয়: অ্যাসাইনমেন্টটি কেবলমাত্র একক কমান্ড দ্বারা দেখা যায়।


2
এই ব্যাখ্যাটি আসলে ভুল, যদিও এটি কয়েকটি কোণার ক্ষেত্রে ব্যতীত সমস্ত ক্ষেত্রেই সঠিক উপসংহারে আসে। আসল ব্যাখ্যাটি হ'ল সম্প্রসারণের ক্রম: $Aকার্য সম্পাদনের আগে মূল্যায়ন করা হয়। আমি মনে করি আপনার ব্যাখ্যা কেবলমাত্র নিয়মিত অন্তর্নির্মিত ইউটিলিটিগুলির ক্ষেত্রে ব্যর্থ হয় যার আচরণের পরিবর্তনশীলটির মান নির্ভর করে: বিল্ট-ইন নির্ধারিত মানটি দেখে। একটি সাধারণ উদাহরণ IFS=: read one two three rest, যা কোলন-বিচ্ছিন্ন ক্ষেত্রগুলি পড়ে: readবিল্টিনটি এর মান দেখতে পায় IFS
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

"বর্তমান শেল নিজেই নয়" ভুল: ভেরিয়েবলটি বর্তমান শেলটিতে সেট করা থাকে তবে এটি কেবল বর্তমান সাধারণ কমান্ডের জন্য স্থায়ী হয়। echoমান দেখতে হবে 10জন্য A, যদি যত্ন।
গিলস 'অশুভ হওয়া বন্ধ করুন'

@ গিলস: স্পষ্টতার জন্য অনেক ধন্যবাদ! আমি এই সূক্ষ্মতা সম্পর্কে অবগত ছিল না। সুতরাং, যদি আমি সঠিকভাবে বুঝতে ব্যাশ হয়েছে জন্য সেটে বর্তমান পরিবেশ অন্যথায় builtins (যা একটি নতুন ডিম না pid) হিসাবে অন্যান্য "regurlar" কমান্ড would নিয়োগ না দেখতে হবে। অ্যাসাইনমেন্ট সুযোগ সীমাবদ্ধ করার জন্য কমান্ডটি করার পরে এটি আনসেট হয়। এটি কি সঠিক, আমি সেই অনুযায়ী আমার উত্তর ঠিক করব। পিএস: প্রযুক্তিগত দিকগুলি বাদ দিয়ে, আমি এখনও মনে করি একটি উত্তরের সুযোগের দিকটির উপর জোর দেওয়া উচিত, মূল্যায়নের আদেশ নয়, অন্যথায় কেউ ভাবতে পারে A=10 test; echo $A10 মুদ্রণ করবে
MestreLion

3

আপনি সম্ভবত যা চান তা করার একটি সম্ভবত পরিষ্কার উপায় হ'ল আদেশটি জারি করা:

A=10 eval 'echo $A'

যা ফলস্বরূপ পরবর্তী মানের হিসাবে 10 এর মান প্রতিস্থাপিত করবে ie এ এর ​​স্থানে (অর্থাত্ 'ইওল'র ভিতরে', যা ইতিমধ্যে নিয়োগ সম্পর্কে জানে)। নোট করুন যে একক উদ্ধৃতি অপরিহার্য। এই ধরনের একটি কনস্ট্রাক্ট আপনার বর্তমান পরিবেশকে দূষিত করার ঝুঁকি না চালিয়ে আপনার পছন্দসই কমান্ডের (এই ক্ষেত্রে প্রতিধ্বনি) অ্যাসাইনমেন্টটি পরিষ্কারভাবে যোগাযোগ করে।

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