$ {! FOO} এবং zsh


13

${!FOO}এতে একটি ডাবল প্রতিস্থাপন সম্পাদন করে bash, এর অর্থ এটি FOO এর (স্ট্রিং) মান গ্রহণ করে এবং এটি একটি পরিবর্তনশীল নাম হিসাবে ব্যবহার করে।
zshএই বৈশিষ্ট্য সমর্থন করে না।

এই কাজটি একই রকম করার কোনও উপায় কি bashএবং zsh?

পটভূমি:

আমি যেমন পরিবেশের ভেরিয়েবলের একটি তালিকা পেয়েছি

PATH MAIL EDITOR

এবং প্রথমে ভেরিয়েবলের নাম এবং তার মানগুলি মুদ্রণ করতে চাই।

এটি এতে কাজ করে bashতবে তা নয় zsh:

for VAR in LIST
do
        echo $VAR
        echo ${!VAR}
done

এটি কোনওভাবেই "পুরানো পথ" দিয়ে হওয়া উচিত eval, তবে আমি এটি কাজ করতে পারি না:

for VAR in LIST
do
        echo $VAR
        echo `eval \$$VAR`
done

আমি কখনই বুঝতে চাইছি না কেন আমি অনিয়মিত গভীর প্রতিস্থাপনের মতো ${${VAR}}বা ${${${VAR}}}প্রয়োজনের পরেও করতে পারি না , তাই এর ব্যাখ্যাও খুব সুন্দর হবে।


1
Hah! আমি ভেবেছিলাম zsh এর আরও বৈশিষ্ট্য থাকার কথা।
Рахматуллин

4
bashএটি নিয়ে বড়াই করার দরকার নেই , এটির একই কার্যকারিতা রয়েছে (এবং আরও অনেক কিছু), কেবলমাত্র একটি ভিন্ন প্যাটার্ন ব্যবহার করে ${(p)FOO}
প্রোফ্যাশট

2
@।, Zsh- র (e)প্যারামিটার সম্প্রসারণ পতাকাটি zsh-2.6-beta17 (মে 1996) এ যুক্ত করা হয়েছিল, (P)পতাকাটি 3.1.5-pws-7 (1999) এ ছিল। বাশ এর ${!var}2.0 (ডিসেম্বর 1996) এ।
স্টাফেন চ্যাজেলাস

উত্তর:


18

বাশ এবং জেডএস উভয়েরই অপ্রত্যক্ষ প্রসার ঘটানোর একটি উপায় রয়েছে তবে তারা বিভিন্ন বাক্য গঠন ব্যবহার করে।

এটি ব্যবহার করে অপ্রত্যক্ষ সম্প্রসারণ করা যথেষ্ট সহজ eval; এটি সমস্ত পসিক্স এবং বেশিরভাগ বোর্ন শেলগুলিতে কাজ করে। মানটিতে শেলটির একটি বিশেষ অর্থ রয়েছে এমন ক্ষেত্রে সঠিকভাবে উদ্ধৃতি দেওয়ার জন্য খেয়াল করুন।

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

${${VAR}}কাজ করে না কারণ এটি কোনও শেল প্রয়োগ করে এমন কোনও বৈশিষ্ট্য নয়। ধনুর্বন্ধকের অভ্যন্তরের জিনিসটি অবশ্যই সিনট্যাক্স নিয়মের সাথে মেনে চলতে হবে যা অন্তর্ভুক্ত নয় ${VAR}। (জেডএসে, এটি সিনট্যাক্স সমর্থিত, তবে আলাদা কিছু করে: নেস্টেড বিকল্পগুলি একই মানের উপর ধারাবাহিক রূপান্তর সম্পাদন করে; যেহেতু এটি মূল্যের উপরে দু'বার পরিচয় রূপান্তর সম্পাদন করে ${${VAR}}equivalent$VAR


19

মূল প্রশ্নটির অধীনে প্রোফ্যাটস মন্তব্যটি ${(p)FOO}একটি পরোক্ষ চলক উল্লেখের বিষয়বস্তু আউটপুট দেওয়ার উদাহরণ দেয় । পতাকাটি ভুল বা একটি টাইপো, এটি একটি মূলধন P হওয়া উচিত এবং ছোট কেস নয়। ব্যবহার করুন: ${(P)FOO}

নিম্নলিখিতগুলি কাঙ্ক্ষিত আউটপুট উত্পাদন করা উচিত:

#! /bin/zsh
LIST=(PATH MAIL EDITOR)
for VAR in ${LIST}
do
    print "${VAR}:  ${(P)VAR}"
done

থেকে zshexpn man পৃষ্ঠা; বিভাগ - প্যারামিটার সম্প্রসারণ পতাকা :

পি

  This forces the value of the parameter name to be interpreted as a further
  parameter name,  whose  value  will  be used where appropriate.  Note that
  flags set with one of the typeset family of commands (in particular case
  transformations) are not applied to the value of name used in this fashion.

  If used with a nested parameter or command substitution, the result of that
  will be taken as a parameter  name  in the  same  way.   For  example,  if
  you  have  `foo=bar'  and `bar=baz', the strings ${(P)foo}, ${(P)${foo}}, and
  ${(P)$(echo bar)} will be expanded to `baz'

একসময় আমি পড়লাম কেন ${${${VAR}}}আপনি প্রত্যাশিত আউটপুট উত্পাদন করে না, তবে এই মুহুর্তে এটি খুঁজে পাচ্ছি না। আপনি নিম্নলিখিত মত কিছু করতে পারেন:

first="second" ; second="third" ; third="fourth" ; fourth="fifth"
print ${(P)${(P)${(P)first}}}
fifth

3

আপনি সঠিকভাবে eval ব্যবহার করছেন না। আপনার উদাহরণে "$" (যেমন `AL VALUE ') এর সাথে পূর্ববর্তী $ VAR এর মানটি একটি আদেশ হিসাবে কার্যকর হবে। আপনি যা চান তা তা নয়। আপনি কোনও ভেরিয়েবলের প্রসারকে মূল্যায়ন করতে চান যার নামটি অন্য ভেরিয়েবল থেকে নেওয়া হয়েছে।

$ for i in `echo PATH MAIL EDITOR`; 
    do eval moo="\${$i}" 
    echo $moo 
done
/usr/local/sbin:/usr/local/bin:/usr/sbin:/u (...)
/var/mail/root
nano

0

{ba,z}sh সমাধান

এখানে একটি ফাংশন যা {বা, z z sh উভয় ক্ষেত্রেই কাজ করে। আমি বিশ্বাস করি এটি পসিক্সও অনুগত।

এটি সতর্ক করে যখন দেওয়া হয়:

  • নাল ইনপুট
  • একাধিক যুক্তি
  • একটি পরিবর্তনশীল নাম যা সেট করা হয়নি

# Expand the variable named by $1 into its value. Works in both {ba,z}sh
# eg: a=HOME $(var_expand $a) == /home/me
var_expand() {
  if [ "$#" -ne 1 ] || [ -z "${1-}" ]; then
    printf 'var_expand: expected one non-empty argument\n' >&2;
    return 1;
  fi
  eval printf '%s' "\"\${$1?}\""
}

পসিক্সে নেই functionবা নেই । [[...]]sh
স্টাফেন চেজেলাস

কোনও যুক্তির জন্য চেকটি হওয়া উচিত নয় [ "$#" -eq 0 ](বা সম্ভবত [ "$#" -ne 1 ]আপনি কেবল একটি যুক্তির প্রত্যাশা করছেন)।
স্টাফেন চেজেলাস

@ স্টাফেনচেজেলাস ধন্যবাদ, আপডেট হয়েছে। POSIX সম্মতি জন্য একটি রেফারেন্স শেল আছে? আমি ভাবছি shell-checkখুব সাহায্য করতে পারে।
টম হেল

@ স্টাফেনচাজেলাস পুনরায় পরীক্ষা করুন, আমি যখন কোনও একক নাল যুক্তি দেওয়া হয় তখনও ব্যর্থ হতে চাই। আমি আপনার ২ য় পরামর্শ যুক্ত করেছি। চিয়ার্স!
টম হেল

আমি ${1-}প্রদত্ত a='"" -o -n 1' [ -z $a ]== উদ্ধৃতি দিয়ে সম্মত 0। তবে $#সবসময় কি একক টোকেন হবে না ?
টম হেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.