একটি ভেরিয়েবল রেফারেন্স "ভিতরে" অন্য ভেরিয়েবল ব্যবহার করুন


27

আমি নিশ্চিত যে এটি তুলনামূলকভাবে সহজ, আমি কীভাবে এটি করব তা জানি না।

#!/usr/bin/ksh
set `iostat`
myvar=6

আমি এমন কিছু চাই echo ${$myvar}যা আমি ${$myvar}-> ${6}-> হিসাবে ব্যাখ্যা করতে চাইvalue


4
প্রযুক্তিগত শব্দটি ভেরিয়েবল ইন্ডিরেশন
থোর

উত্তর:


29

আপনি এটি দিয়ে eval, ksh সহ অনেকগুলি সূক্ষ্ম শেলের সাথে অন্তর্নির্মিত কাজটি করতে পারেন :

#!/usr/bin/ksh
set $(iostat)
myvar=6
eval "echo \${$myvar}"

কৌশলটি হ'ল আপনি যে স্ট্রিংটি খাচ্ছেন তাতে ডাবল-কোট করা evalযাতে $ মাইভারটি "6" এর সাথে প্রতিস্থাপিত হয় এবং বাইরের ডলার-সাইনকে ব্যাকস্ল্যাশ করতে পারে, যাতে evalস্ট্রিংটি "$ 6" পায়।

আউটপুটটির জন্য আমি "% ব্যবহারকারী" পেয়েছি, তবে আমি এটি একটি মাল্টি-প্রসেসর আরএইচইএল মেশিনে চেষ্টা করেছি।


4
আপনি আনুষ্ঠানিকভাবে সপ্তাহের বি / সি এর সর্বোচ্চ উঁচু গ্র্যান্ড মাস্টার যা এমনকি ওপেনবিএসডি 5.4-এ অবিস্মরণীয় ভয়ংকর ksh (সত্যিকারের pdksh) এ কাজ করে। আপনি যদি ভেরিভিটির নাম ভের ভিএন- তে থাকে তার মানটির জন্য যদি ভার্ভিভি সেট করতে চান তবে ঠিক করুন । অসংখ্য ধন্যবাদ! vv=$( eval "echo \$$vn" )
এক্সিকিউনেক্সট

25

পরোক্ষ চলক উল্লেখ

আধুনিক উন্নত শেলগুলির একটি ভেরিয়েবলের মান উল্লেখ করার জন্য একটি পদ্ধতি রয়েছে যার নামটি অন্য ভেরিয়েবলে সঞ্চিত। দুর্ভাগ্যক্রমে পদ্ধতিটি ksh, bash এবং zsh এর মধ্যে পার্থক্য করে।

Mksh ≥R39b এ, আপনি myvarএকটি নামরেফ তৈরি করতে পারেন :

typeset -n myvar=6
echo "$myvar"

এটি এটিটি ksh93 তে কাজ করে না কারণ এটি অবস্থানীয় পরামিতিগুলিতে নেমারেফ সমর্থন করে না। আপনার যেখানে ভেরিয়েবলের একটি ভেরিয়েবলের নাম রয়েছে সেখানে আপনি এই পদ্ধতিটি ব্যবহার করতে পারেন।

foo=bar
typeset -n myvar=foo
echo "$myvar"  # prints bar

ব্যাশ ≥2.0 এ, আপনি লিখতে পারেন

echo "${!myvar}"

Zsh এ, আপনি লিখতে পারেন

echo ${(P)myvar}

আপনি যদি একটি পরিবর্তনশীল অন্য পরিবর্তনশীল নাম ধারণকারী আছে এবং এই ভেরিয়েবলের মান ব্যবহার করতে চান যখন ksh88 এবং pdksh, আপনার একমাত্র আশ্রয় সহ পুরোনো শেল সালে eval, যেমন ব্রুস Ediger দ্বারা ব্যাখ্যা । এই দ্রবণটি কোনও বোর্ন / পসিক্স শেলটিতে কাজ করে।

eval "value=\${$myvar}"
echo "$value"

একটি অ্যারে ব্যবহার করা

এটি এখানে সেরা পদ্ধতি: এটি সহজ এবং আরও বহনযোগ্য।

আপনার ব্যবহারের ক্ষেত্রে, অ্যারে সহ সমস্ত শেল (সমস্ত ksh রূপ, বাশ ≥2.0, zsh), আপনি একটি অ্যারে ভেরিয়েবলকে বরাদ্দ করতে পারেন এবং আপনার পছন্দসই উপাদানটি নিতে পারেন। সাবধান থাকুন যে ksh এবং বাশ অ্যারেগুলি 0 থেকে সংখ্যা শুরু করে তবে zsh 1 থেকে শুরু হবে যদি না আপনি ইস্যু করেন setopt ksh_arraysবা না করেন emulate ksh

set -A iostat -- $(iostat)
echo "${iostat[5]}"

আপনি যদি অ্যারে ভেরিয়েবলে অবস্থানগত পরামিতিগুলি অনুলিপি করতে চান a:

set -A a -- "$@"

Ksh93, mksh ≥R39b, bash ≥2.0 এবং zsh এ আপনি অ্যারে অ্যাসাইনমেন্ট সিনট্যাক্স ব্যবহার করতে পারেন:

iostat=($(iostat))
echo "${iostat[5]}"

বাহ, আপনার 'বোর্ন / পসিক্স' সমাধান ওপেনবিএসডি 5.4 এর ksh / pdksh এও কাজ করে। উপরের ব্রুস এডিগার এর উত্তরটিতে আমার মন্তব্যে এটি উদাহরণটিতে প্রয়োগ করার জন্য, কেবলমাত্র করুন eval "vv=\${$vn}"। মেরকি বিউকুপ, দয়াল স্যার।
এক্সিকিউনেক্সট

1

গিলস দ্বারা নির্দেশিত (যিনি bashউত্তরের অংশটি সরবরাহ করেছিলেন ), ব্রুস এডিগারকে (এটি কীভাবে বহনযোগ্যভাবে করা যায় eval) অবৈধ করে না nameref, সাম্প্রতিক সময়ে এটি কীভাবে করা যায় তা এখানে mksh(এবং এটিএন্ডটি ksh93 ব্যতীত - যেমন - @ গিলিস মন্তব্য করেছেন - নামরেফস এটিএন এবং টি কেএসএসে অবস্থানগত পরামিতিগুলি উল্লেখ করতে পারে না, কেবল নামকরণের প্যারামিটারগুলিতে):

#!/bin/mksh
set -- $(iostat)
nameref myvar=6
echo $myvar

উন্নত প্রতিরোধের জন্য --পরে যোগ করা setহয়েছে।


Ksh 93u হিসাবে, নেমারেফগুলি অবস্থানিক পরামিতিগুলি ( typeset: 6: invalid variable name) উল্লেখ করতে পারে না ।
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

0

অ্যারে অন্য ব্যবহার

কিছু সময়ের জন্য ksh বা কোনও বৈকল্পিক ব্যবহার করেন নি, তাই আমি নিশ্চিত নই যে ksh (বা ব্যাশ) এর একই ক্ষমতা রয়েছে কিনা। আমার প্রাথমিক শেলটি zsh। Iostat এর মতো কমান্ডগুলি থেকে আউটপুট পরিচালনা করার সময় আমি অ্যারেগুলি ব্যবহার করি কারণ তারা একাধিক লাইন তৈরি করে এবং সমস্ত লাইন একই বিন্যাস / দৈর্ঘ্য নয়।

#! /bin/zsh
IOStatOutput=("${(@f)$(iostat)}") # Produces one element per line

উপরোক্ত অবস্থানগত পরামিতিগুলির ব্যবহারকেও বাইপাস করে। এখন, আপনি যদি ডিভাইসের একটি অ্যারে তৈরি করতে চান, তবে বলুন:

for Element in {7..${#IOStatOutput}} # Devices listed in elements 7 thru the last
do
    DevList+=( ${${=IOStatOutput[Element]}[1]} )
done

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

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