ভেরিয়েবলের মাধ্যমে লুপ করুন


16

আমি প্রায় 20 টি বিভিন্ন সার্ভারে আরএসসিএনসি ব্যবহার করতে এবং ফাইল আপডেট করতে বাশ স্ক্রিপ্ট লিখছি।

আমার আরএসএনসি অংশটি বের হয়েছে। যা নিয়ে আমার সমস্যা হচ্ছে তা ভেরিয়েবলের একটি তালিকা দিয়ে চলছে।

আমার স্ক্রিপ্টটি এখনও পর্যন্ত এটি দেখতে দেখতে:

#!/bin/bash
SERVER1="192.xxx.xxx.2"
SERVER2="192.xxx.xxx.3"
SERVER3="192.xxx.xxx.4"
SERVER4="192.xxx.xxx.5"
SERVER5="192.xxx.xxx.6"
SERVER6="192.xxx.xxx.7"

for ((i=1; i<7; i++))
do
    echo [Server IP Address]
done

[Server IP Address]সম্পর্কিত ভেরিয়েবলের মান কোথায় হওয়া উচিত। সুতরাং আমি যখন = 1 আমার $ SERVER1 এর মান প্রতিধ্বনিত করা উচিত।

আমি এটি সহ কয়েকটি পুনরাবৃত্তি চেষ্টা করেছি

echo "$SERVER$i"    # printed the value of i
echo "SERVER$i"     # printer "SERVER" plus the value of i ex: SERVER 1 where i = 1
echo $("SERVER$i")  # produced an error SERVER1: command not found where i = 1
echo $$SERVER$i     # printed a four digit number followed by "SERVER" plus the value of i
echo \$$SERVER$i    # printed "$" plus the value of i

আমি স্ক্রিপ্ট করার পরে অনেক দিন হয়ে গেছে তাই আমি জানি যে আমি কিছু অনুপস্থিত। প্লাস আমি নিশ্চিত যে আমি সি # ব্যবহার করে যা করতে পারি তাতে আমি মিশ্রিত করছি যা আমি গত 11 বছর ধরে ব্যবহার করেছি।

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

এই সমস্ত কোডের ব্লকের পুনরাবৃত্তি না করার প্রয়াসে আমি দূরবর্তী সার্ভারে ফাইলগুলি সিঙ্ক করতে ব্যবহার করব।


সমস্ত প্রতিক্রিয়া এবং মন্তব্যের জন্য ধন্যবাদ। আমি সম্ভবত অ্যারে পদ্ধতির গ্রহণ করব।
পল স্টোনার

উত্তর:


33

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

#! /bin/bash
servers=( 192.xxx.xxx.2 192.xxx.xxx.3
          192.xxx.xxx.4 192.xxx.xxx.5
          192.xxx.xxx.6 192.xxx.xxx.7
)

for server in "${servers[@]}" ; do
    echo "$server"
done

6
+1 টি; এবং নোট করুন যে আপনি অ্যারে উপাদানগুলির আগে / পরে / পরে স্বেচ্ছাসেবী স্থাপন করতে পারেন, যাতে আপনি ওপি হিসাবে লাইন প্রতি একটি উপাদান রাখতে পারেন।
রুখ

@রুখ: ধন্যবাদ, কী করা যায় তা প্রদর্শন করার জন্য আপডেট করা হয়েছে।
চোরোবা

28

অন্যান্য উত্তরগুলি নির্দেশ করে যেহেতু একটি অ্যারে এটি করার সবচেয়ে সুবিধাজনক উপায়। তবে সম্পূর্ণতার জন্য, আপনি যে সঠিক জিনিসটির জন্য জিজ্ঞাসা করছেন তা হ'ল পরোক্ষ প্রসার । নীচে পুনরায় লিখিত, আপনার নমুনা এই পদ্ধতি ব্যবহার করেও কাজ করবে:

#!/bin/bash
SERVER1="192.xxx.xxx.2"
SERVER2="192.xxx.xxx.3"
SERVER3="192.xxx.xxx.4"
SERVER4="192.xxx.xxx.5"
SERVER5="192.xxx.xxx.6"
SERVER6="192.xxx.xxx.7"

for ((i=1; i<7; i++))
do
    servervar="SERVER$i"
    echo "${!servervar}"
done

আপনি যদি ঠিকানার মধ্যে আইপি ঠিকানার তালিকা রেখে দিয়ে থাকেন for লুপের তবে আপনার যা প্রয়োজন তা পুনরুক্ত করার জন্য আপনি কেবল কিছু ব্রেস প্রসার ব্যবহার করে বিবেচনা করতে পারেন:

#!/bin/bash

for server in \
192.xxx.xxx.{2..7} \
192.yyy.yyy.{42..50} \
192.zzz.zzz.254
do
    echo "$server"
done

তবে যদি আপনার (সম্ভবত ব্রেস-প্রসারিত) তালিকাটি পুনরায় ব্যবহার করা দরকার হয়, তবে অ্যারে শুরু করার জন্য তালিকাটি ব্যবহার করার উপায় হবে:

#!/bin/bash

servers=(
192.xxx.xxx.{2..7} 
192.yyy.yyy.{42..50}
192.zzz.zzz.254 )

for server in "${servers[@]}"
do
    echo "$server"
done

14

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

for name in "${!SERVER*}"; do
    echo "${!name}"
done

বা, 4.3 এবং তারপরে আপনি একটি ব্যবহার করতে পারেন nameref:

declare -n name
for name in "${!SERVER*}"; do
    echo "$name"
done

<4.3 সমাধানের জন্য টুপি টিপ ইলক্কাচু


2
পরোক্ষ সম্প্রসারণ ( ${!var}) বাশের পুরানো সংস্করণগুলির সাথেও কাজ করে:foo1=aa; foo2=bbb; foox=cccc; for p in "${!foo@}"; do echo "$p = ${!p}"; done
ইলক্কাচু

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

6

আপনার অ্যারে ব্যবহার করা উচিত বলেছে এমন প্রত্যেকেই সঠিক, তবে - একাডেমিক অনুশীলন হিসাবে - যদি আপনি কোনও সংখ্যায় (SERVER1, SERVER2, ইত্যাদি) সমাপ্ত পৃথক ভেরিয়েবলগুলি দিয়ে এটি করার জন্য দৃ determined়সংকল্পবদ্ধ হন, আপনি এভাবেই করতেন এটা:

for ((i=1; i<7; i++))
do
    eval echo \"\$SERVER$i\"
done

evalনিরাপদে ব্যবহার করা শক্ত। হ্যাঁ এটি কাজ করতে পারে, তবে বাশ পরোক্ষ প্রসার সাধারনত একটি ভাল উপায়।
পিটার কর্ডস

অভ্যাস। আমি যখন শেল স্ক্রিপ্টগুলি লিখতে শুরু করেছি, এমনকি ব্যাশেও, সেখানে কোনও পরোক্ষ প্রসার ছিল না। কীভাবে সঠিকভাবে পালানো যায় তা বুঝতে পারলে "ইভাল" পুরোপুরি নিরাপদ। তবুও, আমি আপনাদের সাথে একমত হই যে পরোক্ষ সম্প্রসারণ আরও ভাল ... তবে পুরানো উপায়গুলি এখনও কার্যকর হয়। আমি যাই হোক না কেন এই ক্ষেত্রে না করতাম। আমি একটি অ্যারে ব্যবহার করব!
বীম ডেভিস

এই ক্ষেত্রে, যে বিজ্ঞপ্তি আপনি উদ্ধৃতি চিহ্ন রক্ষা পেল না, তাই পরে evalসম্পন্ন করা হয় আপনি, echo $SERVER1না echo "$SERVER1"। হ্যাঁ নিরাপদে ব্যবহার করা সম্ভব, তবে অনিরাপদভাবে ব্যবহার করা খুব সহজ বা কীভাবে আপনি ইচ্ছা করেছিলেন!
পিটার কর্ডেস

যেহেতু কোনও সার্ভারের নামটিতে কোনও ফাঁকা স্থান নেই, তবে এটি কোনওভাবেই এই ক্ষেত্রে গুরুত্বপূর্ণ হত না ... তবে আপনি ঠিকই বলেছেন, ডাবল-কোটগুলি এড়ানো উচিত। উত্তরে স্থির!
বীম ডেভিস

ডান, সম্পূর্ণরূপে ডাবল-কোটগুলি সরিয়ে ফেলা (তারা যে কোনও কিছু রক্ষা করছে এমন বিভ্রান্তিকর ছাপ এড়াতে) অন্য বিকল্প হবে। তবে সেগুলি থেকে পালানো আরও সাধারণ উপায়, সুতরাং +1।
পিটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.