কমান্ডে বাশ স্ক্রিপ্টের অস্থায়ী মান


11

কমান্ড নীচের মত,

if true; then
   IFS=":" read a b c d e f <<< "$test"

বইটি বলেছে যখন IFS ":"মূল আদেশ ( read a b c d e f <<< "$value") এর আগে ভ্যালু অ্যাসাইনমেন্ট কমান্ড ( ) ব্যবহার করা হয় , তখন এর মানটি প্রধান কমান্ডের উপর অস্থায়ীভাবে কার্যকর হয়। সুতরাং, readকমান্ডটি ডিলিমিটার ব্যবহার করে :

তবে, এই আদেশের মতো,

if true; then
   HOME="hello" echo "$HOME"

ইকো বার্তা হ্যালো নয়। উপরের কমান্ডের আসল অর্থ কী?

উত্তর:


5

এটি মূল্যায়ন কীভাবে কাজ করে তা একটি প্রশ্নে নেমে আসে। উভয় উদাহরণ একইভাবে কাজ করে, শেল (বাশ, এখানে) ভেরিয়েবলগুলি কীভাবে প্রসারিত করে তার কারণে সমস্যাটি ঘটে।

আপনি যখন এই আদেশটি লিখবেন:

HOME="foo" echo $HOME

$HOMEসম্প্রসারিত করা হয় আগে কমান্ড চালানো হয় । অতএব, এটি কমান্ডের জন্য সেট করে রেখেছেন এমনটি নয় তবে এটি মূল মানে প্রসারিত হবে। HOMEপরিবর্তনশীল প্রকৃতপক্ষে পরিবেশের মধ্যে পরিবর্তন করা হয়েছে echoকমান্ড চলমান, কিন্তু, আপনি মুদ্রণ করা হয় $HOMEপিতা বা মাতা থেকে।

উদাহরণস্বরূপ, এটি বিবেচনা করুন:

$ HOME="foo" bash -c 'echo $HOME'
foo
$ echo $HOME
/home/terdon

আপনি উপরে দেখতে পাচ্ছেন, প্রথম কমান্ড অস্থায়ীভাবে পরিবর্তিত মানটির HOMEমুদ্রণ করে এবং দ্বিতীয়টি মূল মুদ্রণ করে, এটি দেখায় যে চলকটি কেবল অস্থায়ীভাবে পরিবর্তিত হয়েছিল। যেহেতু bash -c ...কমান্ডটি ডাবলগুলি ( ' ') এর পরিবর্তে একক উদ্ধৃতি ( ) এ আবদ্ধ রয়েছে " ", ভেরিয়েবলটি প্রসারিত হয় না এবং নতুন বাশ প্রক্রিয়া হিসাবে যেমন হয় তেমনটি পাস হয়। এই নতুন প্রক্রিয়াটি এরপরে এটি প্রসারিত করে এবং এটিতে সেট করা নতুন মানটি মুদ্রণ করে। আপনি যদি এটি ব্যবহার করেন তবে এটি ঘটতে দেখবেন set -x:

$ set -x
$ HOME="hello" echo "$HOME"
+ HOME=hello         
+ echo hello
hello

আপনি উপরে দেখতে পারেন যে ভেরিয়েবলটি $HOME কখনও পাস হয় না echo। এটি কেবল এর প্রসারিত মান দেখে। তুলনা করা:

$ HOME="hello" bash -c 'echo $HOME'
+ HOME=hello
+ bash -c 'echo $HOME'
hello

এখানে, একক উদ্ধৃতিগুলির কারণে, ভেরিয়েবল এবং এর মানটি নয় নতুন প্রক্রিয়াতে প্রেরণ করা হয়।


7

শেলটি যখন একটি রেখাকে পার্স করছে, এটি লাইনটিকে শব্দের সাথে টোকানাইজ করবে, শব্দের উপর বিভিন্ন প্রসার (ক্রম) সম্পাদন করবে, তারপরে কমান্ডটি কার্যকর করবে।

অনুমান করা test=1:2:3:4:5:6

আসুন এই আদেশটি দেখুন: IFS=":" read a b c d e f <<< "$test"

টোকেনাইজিংয়ের পরে এবং প্যারামিটার সম্প্রসারণ ঘটে:IFS=":" read a b c d e f <<< "1:2:3:4:5:6"

শেলটি পড়ার কমান্ডের সময়কালের জন্য আইএফএস ভেরিয়েবল সেট করবে এবং readকীভাবে ইনপুটটিতে $ আইএফএস প্রয়োগ করতে হবে এবং ভেরিয়েবলের নামগুলিতে মান প্রদান করবে।

এই আদেশের একটি অনুরূপ গল্প রয়েছে তবে ভিন্ন ফলাফল: HOME="hello" echo "$HOME"

যেহেতু কমান্ড শুরুর আগে প্যারামিটার সম্প্রসারণ ঘটে , শেলটি রয়েছে:

HOME="hello" echo "/home/username"

এবং তারপরে, ইকো কমান্ডটি প্রয়োগ করার সময়, value HOME এর নতুন মানটি মোটেই ব্যবহৃত হয় না।

আপনি যা করার চেষ্টা করছেন তা অর্জন করতে, একটি বেছে নিন

# Delay expansion of the variable until its new value is set
HOME="hello" eval 'echo "$HOME"'

অথবা

# Using a subshell, so the altered env variable does not affect the parent.
# The semicolon means that the variable assignment will occur before
# the variable expansion
(HOME="hello"; echo "$HOME")

তবে প্রথমটি বেছে নাও।


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

evalসমাধান এড়ানো উচিত কেন ?
ডার্কহার্ট

আপনি যদি ইনপুটটিকে কঠোরভাবে নিয়ন্ত্রণ না করেন তবে আপনাকে কোড সম্পর্কে খুব সতর্কতা অবলম্বন করতে হবে যা আপনি অন্য লোককে আপনার প্রোগ্রামে ইনজেকশনের অনুমতি দেন।
গ্লেন জ্যাকম্যান

-1

দুটি স্কোপ রয়েছে: এনভায়রনমেন্ট ভেরিয়েবল এবং লোকাল ভেরিয়েবল। পরিবেশের ভেরিয়েবলগুলি প্রতিটি প্রক্রিয়া (দেখুন setenv, getenv) এর জন্য বৈধ , যখন স্থানীয় ভেরিয়েবলগুলি কেবল এই শেল সেশনের মধ্যেই সক্রিয় থাকে। (এটি কোনও স্পষ্ট পার্থক্য নয় ...)

অন্তর্নিহিত env(আপনার উদাহরণ হিসাবে) পরিবেশ পরিবর্তন করে, echo ...স্থানীয়গুলি ব্যবহার করার সময় - envএর কোনও প্রভাব নেই।

স্থানীয় ভেরিয়েবলগুলি পরিবর্তন করতে, বলুন,

( HOME="foo" ; echo "$HOME" )

এখানে প্রথম বন্ধনীগুলি এই কার্যভারের ক্ষেত্রটি নির্ধারণ করে।


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