ভেরিয়েবলের নামটি স্ট্রিং হিসাবে সংরক্ষণ করা হয় তবে ভেরিয়েবলের মান কীভাবে পাওয়া যায়?


142

স্ট্রিং হিসাবে ভেরিয়েবলের নাম থাকলে আমি কীভাবে ব্যাশ ভেরিয়েবলের মানটি পুনরুদ্ধার করতে পারি?

var1="this is the real value"
a="var1"
Do something to get value of var1 just using variable a.

প্রসঙ্গ:

আমার কিছু এএমআই এর ( অ্যামাজন মেশিন ইমেজ ) রয়েছে এবং আমি প্রতিটি এএমআইয়ের কয়েকটি উদাহরণ সন্ধান করতে চাই। তারা বুট করা শেষ করার সাথে সাথে আমি প্রতিটি এএমআই টাইপ অনুসারে সেটআপ করতে চাই। আমি কোনও এএমআই-র ভিতরে প্রচুর স্ক্রিপ্ট বা গোপন কীগুলি বেক করতে চাই না তাই আমি একটি সাধারণীকরণের স্টার্টআপ স্ক্রিপ্ট প্রস্তুত করেছি এবং আমি এটি সর্বজনীনভাবে অ্যাক্সেসযোগ্য লিঙ্কের সাথে এস 3 এ রেখেছি । Rc.local এ আমি কোডের একটি ছোট টুকরো রেখেছি যা প্রারম্ভিক স্ক্রিপ্টটি এনে এটি কার্যকর করে। এএমআইতে আমার যা কিছু আছে তা এই। তারপরে প্রতিটি এএমআই একটি সাধারণ কনফিগারেশন স্ক্রিপ্ট অ্যাক্সেস করে যা প্রতিটি এএমআই এবং প্রত্যেকটির জন্য বিশেষ সেটআপ স্ক্রিপ্টগুলির জন্য প্রযোজ্য। এই স্ক্রিপ্টগুলি ব্যক্তিগত এবং এগুলি অ্যাক্সেস করার জন্য একটি স্বাক্ষরিত URL প্রয়োজন।

সুতরাং এখন, আমি যখন একটি এএমআই (my_private_ami_1) এর একটি উদাহরণ ফায়ার করি তখন আমি এস 3 তে উপস্থাপিত আরও একটি ফাইলের জন্য একটি স্বাক্ষরিত ইউআরএল পাস করি যা কী / মান জোড়ার ক্ষেত্রে সমস্ত প্রাইভেট স্ক্রিপ্টগুলির জন্য স্বাক্ষরিত URL রয়েছে।

config_url="http://s3.amazo.../config?signature"
my_private_ami_1="http://s3.amazo.../ami_1?signature"
...
যখন স্টার্টআপ স্ক্রিপ্টটি চলে, তখন এটি উপরের ফাইলটি ডাউনলোড করে sourceএটি s তারপরে এটি এর এএমআই টাইপ পরীক্ষা করে এবং নিজের জন্য সঠিক সেটআপ স্ক্রিপ্টটি বাছাই করে।

ami\_type=GET AMI TYPE #ex: sets ami\_type to my\_private\_ami\_1
setup\_url=GET THE SETUP FILE URL BASED ON AMI\_TYPE # this is where this problem arises

সুতরাং এখন আমার কাছে একটি জেনেরিক কোড থাকতে পারে যা এএমআই প্রকারের উদাহরণগুলিতে আগুন ধরিয়ে দিতে পারে এবং উদাহরণগুলি নিজের যত্ন নিতে পারে।

উত্তর:


257

আপনি ব্যবহার করতে পারেন ${!a}:

var1="this is the real value"
a="var1"
echo "${!a}" # outputs 'this is the real value'

এটি পরোক্ষ প্যারামিটার বিস্তারের উদাহরণ :

প্যারামিটার সম্প্রসারণের মূল রূপটি ${parameter}। এর মান parameterপ্রতিস্থাপিত হয়।

এর প্রথম চরিত্রটি parameterযদি একটি বিস্ময়বোধক বিন্দু (!) হয় তবে এটি ভেরিয়েবল ইন্ডিয়ারেশনের একটি স্তর প্রবর্তন করে। বাশ ভেরিয়েবলের parameterনাম হিসাবে বাকী থেকে গঠিত ভেরিয়েবলের মান ব্যবহার করে ; এই পরিবর্তনশীলটি তখন প্রসারিত হয় এবং সেই মানটি parameterনিজের মানের পরিবর্তে বাকী বিকল্পটিতে ব্যবহৃত হয়।


4
এটি আমার জন্য ওএসএক্স ব্যাশে কাজ করে, তবে ডেবিয়ান নয়? ডেবিয়ানে আমি Bad substitutionত্রুটি পাই ।
23inhouse

11
@ 23inhouse আপনি কি আপনার স্ক্রিপ্টটি ব্যবহার করছেন /bin/sh? যদি তা হয় তবে /bin/bashপরিবর্তে ব্যবহার করার চেষ্টা করুন । দেবিয়ান স্কুইজ থেকে /bin/shতার পরিবর্তে একটি সিমিলিংকdashbash হিসাবে পরিবর্তিত হয়েছিল । dashএই নির্দিষ্ট বাক্য গঠন সমর্থন করে না এবং একটি Bad substitutionত্রুটি আউটপুট হবে ।
ফিল রস

8
কোনও অ্যারে সম্পর্কিত যে পরিবর্তনশীল নামের জন্য এই কাজটি করার কোনও উপায় আছে?
লুপ্যাক্স

বাশ দিয়ে উবুন্টুতে কাজ করে
সের্গেই পি। ওরফে অ্যাজুরে

1
@ ডোরনশাই এটি পরোক্ষ প্যারামিটার সম্প্রসারণের একটি উদাহরণ, gnu.org/software/bash/manual/html_node/…
ফিল রোস

29
X=foo
Y=X
eval "Z=\$$Y"

জেডকে "foo" সেট করে

ব্যবহারের ক্ষেত্রে যত্ন নিনeval যেহেতু এটি মানগুলির মাধ্যমে কোডের যথাযথ বিসর্জনের অনুমতি দিতে পারে ${Y}। এটি কোড ইঞ্জেকশনের মাধ্যমে ক্ষতির কারণ হতে পারে।

উদাহরণ স্বরূপ

Y="\`touch /tmp/eval-is-evil\`"

তৈরি করতে হবে /tmp/eval-is-evil। এটি rm -rf /অবশ্যই কিছু হতে পারে ।


আমার লেজটি বাঁচিয়েছে,
রাইফিয়ান

9

আমার অনুসন্ধানের কীওয়ার্ডগুলি সংশোধন করে পেয়েছে :)।

eval a=\$$a
আপনার সময় জন্য ধন্যবাদ।


ইওল ব্যবহার করে যত্ন নিন কারণ এটি মানগুলির মাধ্যমে কোডের যথাযথ বিসর্জনের অনুমতি দিতে পারে ${Y}। "অনন" ব্যবহারকারীর উত্তরে আমার সংযোজনটি দেখুন।
শেষ পর্যন্ত

এটিই একমাত্র কার্যকরী উত্তর। অদ্ভুত যে এটি আপনার নিজের!
Ctrl এস

8

আমার সহকর্মী zsh ব্যবহারকারীদের জন্য, গ্রহণযোগ্য উত্তর হিসাবে একই জিনিসটি সম্পাদনের উপায়টি হ'ল:

${(P)a}

একে প্যারামিটার নাম প্রতিস্থাপন বলা হয়

এটি প্যারামিটার নামের মানটিকে আরও প্যারামিটারের নাম হিসাবে ব্যাখ্যা করতে বাধ্য করে, যার মান যথাযথ যেখানে ব্যবহার করা হবে। নোট করুন যে কমান্ডগুলির একটি টাইপসেট পরিবারের সাথে সজ্জিত পতাকাগুলি (নির্দিষ্ট ক্ষেত্রে রূপান্তরগুলিতে) এই ফ্যাশনে ব্যবহৃত নামের মান প্রয়োগ করা হয় না।

যদি কোনও নেস্টেড প্যারামিটার বা কমান্ড প্রতিস্থাপনের সাথে ব্যবহার করা হয় তবে এর ফলাফলটি একইভাবে প্যারামিটারের নাম হিসাবে নেওয়া হবে। উদাহরণস্বরূপ, আপনার যদি 'foo = বার' এবং 'বার = বাজ' থাকে তবে স্ট্রিংগুলি $ {(পি) foo}, $ {(পি) $ oo ফু}}, এবং $ {(পি) $ (প্রতিধ্বনি বার) রয়েছে '' বাজ 'এ প্রসারিত হবে।

তেমনি, যদি রেফারেন্সটি নিজেই বাসা বেঁধে দেওয়া হয়, পতাকাটির সাথে অভিব্যক্তিটিকে এমনভাবে বিবেচনা করা হবে যেন এটি প্যারামিটার নাম দ্বারা সরাসরি প্রতিস্থাপন করা হয়েছিল। যদি এই নেস্টেড প্রতিস্থাপনটি একাধিক শব্দের সাথে অ্যারে তৈরি করে তবে এটি একটি ত্রুটি। উদাহরণস্বরূপ, 'প্যারামিটার অ্যাসোসিয়েটিভ অ্যারে' যেখানে 'নাম = এসোসিয়েশন' হয়, তারপরে '$ {$ {(পি) নাম} [এল্ট]}' এসোসিয়েটিভ সাবস্ক্রিপ্টড 'এল্ট' এর উপাদানটিকে বোঝায়।


0

আধুনিক শেলগুলি ইতিমধ্যে অ্যারেগুলিকে সমর্থন করে (এবং এমনকি এসোসিয়েটিভ অ্যারে)। সুতরাং দয়া করে সেগুলি ব্যবহার করুন এবং কম পরিমাণে useভাল ব্যবহার করুন।

var1="this is the real value"
array=("$var1")
# or array[0]="$var1"

তারপরে আপনি যখন এটি কল করতে চান, তখন প্রতিধ্বনি করুন $ {অ্যারে [0]


যদি আমি কমান্ডলাইন আর্গুমেন্ট (যেমন হিসাবে $1) থেকে স্ট্রিংটি পাই তবে এই কাজ করবে ?
জেনা

0

উত্তরের উপর ভিত্তি করে: https://unix.stackexchange.com/a/111627

###############################################################################
# Summary: Returns the value of a variable given it's name as a string.
# Required Positional Argument: 
#   variable_name - The name of the variable to return the value of
# Returns: The value if variable exists; otherwise, empty string ("").
###############################################################################
get_value_of()
{
    variable_name=$1
    variable_value=""
    if set | grep -q "^$variable_name="; then
        eval variable_value="\$$variable_name"
    fi
    echo "$variable_value"
}

test=123
get_value_of test
# 123
test="\$(echo \"something nasty\")"
get_value_of test
# $(echo "something nasty")

0

অ্যারেগুলির ক্ষেত্রেও একই সমস্যা ছিল, আপনি যদি অ্যারেগুলিও চালাচ্ছেন তবে এটি কীভাবে করবেন তা এখানে:

array_name="ARRAY_NAME"
ARRAY_NAME=("Val0" "Val1" "Val2")

ARRAY=$array_name[@]
echo "ARRAY=${ARRAY}"
ARRAY=("${!ARRAY}")
echo "ARRAY=${ARRAY[@]}"
echo "ARRAY[0]=${ARRAY[0]}"
echo "ARRAY[1]=${ARRAY[1]}"
echo "ARRAY[2]=${ARRAY[2]}"

এটি আউটপুট দেবে:

ARRAY=ARRAY_NAME[@]
ARRAY=Val0 Val1 Val2
ARRAY[0]=Val0
ARRAY[1]=Val1
ARRAY[2]=Val2
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.