প্রক্রিয়াটির জন্য বাশ স্ক্রিপ্ট অপেক্ষা করে এবং রিটার্ন কোড পান


13

আমি একটি স্ক্রিপ্ট তৈরি করার চেষ্টা করছি যা অনেক ব্যাকগ্রাউন্ড কমান্ড শুরু করবে। প্রতিটি ব্যাকগ্রাউন্ড কমান্ডের জন্য আমার রিটার্ন কোডটি পাওয়া দরকার।

আমি নিম্নলিখিত স্ক্রিপ্ট চেষ্টা করা হয়েছে:

 #!/bin/bash
set -x
pid=()
return=()


for i in 1 2
do
 echo start $i
 ssh mysql "/root/test$i.sh" &
 pid[$i]=$!
done

for i in ${#pid[@]}
do
echo ${pid[$i]}
wait ${pid[$i]}
return[$i]=$?

if [ ${return[$i]} -ne 0 ]
then
  echo mail error
fi

done

echo ${return[1]}
echo ${return[2]}

আমার সমস্যাটি ওয়েট লুপ চলাকালীন, যদি দ্বিতীয় পিড প্রথমটির আগে শেষ হয়, আমি রিটার্ন কোডটি পাব না।

আমি জানি যে আমি অপেক্ষা পিড 1 পিড ​​2 চালাতে পারি, তবে এই কমান্ডের সাহায্যে আমি সমস্ত কমান্ডের রিটার্ন কোড পেতে পারি না।

কোন ধারণা ?

উত্তর:


6

আপনি একটি অস্থায়ী ডিরেক্টরি ব্যবহার করে এটি করতে পারেন।

# Create a temporary directory to store the statuses
dir=$(mktemp -d)

# Execute the backgrouded code. Create a file that contains the exit status.
# The filename is the PID of this group's subshell.
for i in 1 2; do
    { ssh mysql "/root/test$i.sh" ; echo "$?" > "$dir/$BASHPID" ; } &
done

# Wait for all jobs to complete
wait

# Get return information for each pid
for file in "$dir"/*; do
    printf 'PID %d returned %d\n' "${file##*/}" "$(<"$file")"
done

# Remove the temporary directory
rm -r "$dir"

9

বিষয়টি আপনার সাথে আরও রয়েছে with

for i in ${#pid[@]}

যা হয় for i in 2

এটি বরং হওয়া উচিত:

for i in 1 2

অথবা

for ((i = 1; i <= ${#pid[@]}; i++))

wait "$pid" হবে সঙ্গে কাজের প্রস্থান কোড আসতে bash(এবং POSIX শাঁস, কিন্তু না zsh) এমনকি যদি কাজ ইতিমধ্যে সমাপ্ত ছিল যখন waitশুরু হয়েছে।


5

অস্থায়ী ফাইল ব্যতীত একটি জেনেরিক বাস্তবায়ন।

#!/usr/bin/env bash

## associative array for job status
declare -A JOBS

## run command in the background
background() {
  eval $1 & JOBS[$!]="$1"
}

## check exit status of each job
## preserve exit status in ${JOBS}
## returns 1 if any job failed
reap() {
  local cmd
  local status=0
  for pid in ${!JOBS[@]}; do
    cmd=${JOBS[${pid}]}
    wait ${pid} ; JOBS[${pid}]=$?
    if [[ ${JOBS[${pid}]} -ne 0 ]]; then
      status=${JOBS[${pid}]}
      echo -e "[${pid}] Exited with status: ${status}\n${cmd}"
    fi
  done
  return ${status}
}

background 'sleep 1 ; false'
background 'sleep 3 ; true'
background 'sleep 2 ; exit 5'
background 'sleep 5 ; true'

reap || echo "Ooops! Some jobs failed"

আপনাকে ধন্যবাদ :-) এটি ঠিক আমি খুঁজছিলাম!
কোরবানী

0

স্টাফেনের উত্তরটি ভাল তবে আমি পছন্দ করব

for i in ${!pid[@]}
do
    wait ${pid[i]}
    return[i]=$?
    unset "pid[$i]"
done

যা pidঅ্যারের কীগুলিতে পুনরাবৃত্তি করবে , এন্ট্রিগুলি এখনও বিদ্যমান তা নির্বিশেষে আপনি এটিকে মানিয়ে নিতে পারেন, লুপটি ভেঙে ফেলতে পারেন এবং পুরো লুপটি পুনরায় শুরু করতে পারেন এবং এটি ঠিক কাজ করবে। এবং iশুরু করার জন্য আপনার ক্রমাগত মানগুলির প্রয়োজন নেই ।

অবশ্যই, আপনি যদি হাজার হাজার প্রক্রিয়া নিয়ে কাজ করে থাকেন তবে আপনার কাছে অপ্রয়োজনীয় তালিকা থাকলে সম্ভবত স্টেপেনের দৃষ্টিভঙ্গি ভগ্নাংশ হিসাবে আরও কার্যকর হবে।

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