বাশে ডু-ওয়েল লুপ অনুকরণ করা


137

বাশে ডু-ওয়েল লুপ অনুকরণ করার সর্বোত্তম উপায় কী?

আমি whileলুপটি প্রবেশের আগে শর্তটি পরীক্ষা করতে পারতাম এবং তারপরে লুপের শর্তটি পুনরায় পরীক্ষা করে চালিয়ে যেতে পারি তবে এটি নকল কোড। একটি পরিষ্কার উপায় আছে?

আমার স্ক্রিপ্টের সিউডো কোড:

while [ current_time <= $cutoff ]; do
    check_if_file_present
    #do other stuff
done

সময়ের check_if_file_presentপরে চালু হলে এটি সম্পাদন করে না $cutoff, এবং একটি কাজ করবে।


আপনি untilস্যুইচ খুঁজছেন ?
মাইকেল গার্ডনার

2
@ মিশেলগার্ডনার লুপটির untilবডি কার্যকর করার আগে শর্তটিও মূল্যায়ন করবে
অ্যালেক্স

2
আহ্, আমি দেখছি, আমি আপনার কোয়ান্ডারিকে ভুল বুঝেছি।
মাইকেল গার্ডনার

উত্তর:


216

দুটি সহজ সমাধান:

  1. কিছুক্ষণ লুপের আগে একবার আপনার কোডটি কার্যকর করুন

    actions() {
       check_if_file_present
       # Do other stuff
    }
    
    actions #1st execution
    while [ current_time <= $cutoff ]; do
       actions # Loop execution
    done
  2. বা:

    while : ; do
        actions
        [[ current_time <= $cutoff ]] || break
    done

9
:একটি অন্তর্নির্মিত, বিল্ট ইন এর সমতুল্য true। তারা উভয়ই "সফলভাবে কিছুই করেনি"।
লক্স্যাক্স

2
@ লক্স্যাক্সগুলি যেমন zsh এ সত্য তবে বাশের ক্ষেত্রে নয়। trueএটি একটি আসল প্রোগ্রাম যেখানে :অন্তর্নির্মিত। প্রাক্তনটি সহজেই 0(এবং falseসাথে 1) পরে উপস্থিত থেকে একেবারে কিছুই করে না। আপনি চেক করতে পারেন which true
ফ্লেশগ্রিন্ডার

@ ফ্লেশগ্রিন্ডার :এখনও trueব্যাশের জায়গায় ব্যবহারযোগ্য । এটি দিয়ে চেষ্টা করুন while :; do echo 1; done
আলেকজ মাগুরা

2
কখনও আলাদা কিছু বলেনি, কেবল এটি trueবাশ-তে অন্তর্নির্মিত নয়। এটি একটি প্রোগ্রাম সাধারণত পাওয়া যায় /bin
ফ্লেশগ্রিন্ডার

type trueব্যাশে (সমস্ত উপায়ে 3.2% তে ফিরে আসা) ফিরে আসে true is a shell builtin। এটি সত্য যে /bin/trueএটি একটি প্রোগ্রাম; সত্য সম্পর্কে যা সত্য নয় তা trueহ'ল এটি কোনও বিল্টিন নয়। (টিএল; ডঃ: সত্য একটি বাশ অন্তর্নির্মিত এবং একটি প্রোগ্রাম)
পিজে এবি

152

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

while 
    check_if_file_present
    #do other stuff
    (( current_time <= cutoff ))
do
    :
done

কোলনের পরিবর্তে, আপনি continueযদি আরও বেশি পঠনযোগ্য দেখতে পান তবে আপনি এটি ব্যবহার করতে পারেন । আপনি একটি কমান্ড সন্নিবেশ করতে পারেন যা কেবল পুনরাবৃত্তির মধ্যে চলবে (প্রথমটির আগে বা শেষের পরে নয়), যেমন echo "Retrying in five seconds"; sleep 5। অথবা মানগুলির মধ্যে ডিলিমিটারগুলি মুদ্রণ করুন:

i=1; while printf '%d' "$((i++))"; (( i <= 4)); do printf ','; done; printf '\n'

আপনি পূর্ণসংখ্যার তুলনা করছেন বলে মনে হয় তাই ডাবল প্রথম বন্ধনী ব্যবহারের জন্য পরীক্ষাটি পরিবর্তন করেছি। ডাবল বর্গাকার বন্ধনীগুলির মধ্যে, তুলনা অপারেটরগুলি<= লেজিকাল এবং উদাহরণস্বরূপ 2 এবং 10 এর তুলনা করার সময় ভুল ফলাফল দেয়। এই অপারেটরগুলি একক বর্গাকার বন্ধনীগুলির মধ্যে কাজ করে না।


এটি কি একক লাইনের সমতুল্য while { check_if_file_present; ((current_time<=cutoff)); }; do :; done? অর্থাৎ whileকন্ডিশনের ভিতরে থাকা কমান্ডগুলি কার্যকরভাবে সেমিকোলন দ্বারা পৃথক করা যায় না যেমন &&, এবং দ্বারা দলবদ্ধ {}?
রুসলান

@ রুসলান: কোঁকড়া ধনুর্বন্ধনী অপ্রয়োজনীয়। ডাবল বন্ধনী ব্যবহার করে &&বা পরীক্ষার সাথে আপনার কোনও কিছু লিঙ্ক করা উচিত নয় ||যেহেতু এটি কার্যকরভাবে তাদেরকে পরীক্ষার অংশ করে তোলে যা নিয়ন্ত্রণ করে while। আপনি যদি এই কমান্ডটি কমান্ড লাইনে ব্যবহার না করেন তবে উদ্দেশ্যটি অপঠনযোগ্য না হওয়ার কারণে আমি এটি ওয়ান-লাইনার হিসাবে (একটি স্ক্রিপ্টে বিশেষত) করব না।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

হ্যাঁ, আমি এটিকে ওয়ান-লাইনার হিসাবে ব্যবহার করার ইচ্ছা করছিলাম না: কেবল পরীক্ষার কমান্ডগুলি কীভাবে সংযুক্ত রয়েছে তা পরিষ্কার করার জন্য। আমি উদ্বিগ্ন ছিলাম যে প্রথম কমান্ড শূন্য-শূন্য নয়, পুরো শর্তটি মিথ্যা হতে পারে।
রুসলান

3
@ আরসলান: না, এটিই শেষ ফেরতের মান। while false; false; false; true; do echo here; break; doneআউটপুটগুলি "এখানে"
পরবর্তী বিজ্ঞপ্তি না হওয়া পর্যন্ত বিরতি দেওয়া

@ থ্যাথোথেরগুই: সামর্থ্যের মধ্যে এটি বেশ দুর্দান্ত! আপনি স্ট্রিংয়ে ডিলিমিটার সন্নিবেশ করানোর জন্য এটি ব্যবহার করতে পারেন। ধন্যবাদ!
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

2

আমরা এর while [[condition]]; do true; doneমতো ব্যাশে ডু-ওয়েল লুপ অনুকরণ করতে পারি :

while [[ current_time <= $cutoff ]]
    check_if_file_present
    #do other stuff
do true; done

একটি উদাহরণ জন্য। বাশ স্ক্রিপ্টে এসএসএস সংযোগ পাওয়ার বিষয়ে আমার বাস্তবায়নটি এখানে :

#!/bin/bash
while [[ $STATUS != 0 ]]
    ssh-add -l &>/dev/null; STATUS="$?"
    if [[ $STATUS == 127 ]]; then echo "ssh not instaled" && exit 0;
    elif [[ $STATUS == 2 ]]; then echo "running ssh-agent.." && eval `ssh-agent` > /dev/null;
    elif [[ $STATUS == 1 ]]; then echo "get session identity.." && expect $HOME/agent &> /dev/null;
    else ssh-add -l && git submodule update --init --recursive --remote --merge && return 0; fi
do true; done

এটি নীচের মত অনুসারে আউটপুট দেবে:

Step #0 - "gcloud": intalling expect..
Step #0 - "gcloud": running ssh-agent..
Step #0 - "gcloud": get session identity..
Step #0 - "gcloud": 4096 SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /builder/home/.ssh/id_rsa (RSA)
Step #0 - "gcloud": Submodule '.google/cloud/compute/home/chetabahana/.docker/compose' (git@github.com:chetabahana/compose) registered for path '.google/cloud/compute/home/chetabahana/.docker/compose'
Step #0 - "gcloud": Cloning into '/workspace/.io/.google/cloud/compute/home/chetabahana/.docker/compose'...
Step #0 - "gcloud": Warning: Permanently added the RSA host key for IP address 'XXX.XX.XXX.XXX' to the list of known hosts.
Step #0 - "gcloud": Submodule path '.google/cloud/compute/home/chetabahana/.docker/compose': checked out '24a28a7a306a671bbc430aa27b83c09cc5f1c62d'
Finished Step #0 - "gcloud"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.