컬과 프로세스 타이머를 동시에 실행

컬과 프로세스 타이머를 동시에 실행

컬 명령을 동시에 실행하고 기본적으로 타이머를 실행하여 완료하는 데 걸리는 시간을 계산하려고 합니다. URL의 응답 시간에 몇 가지 문제가 있으며 90초를 초과하는 경우 컬을 최대 2번까지 다시 실행하는 타이머를 만들고 싶습니다. 세 번째 이후에는 오류 메시지만 표시하고 종료됩니다.

if 및 while 문에서 아래 코드와 유사한 다양한 변형을 시도했지만 콘솔에서 중단할 수 없는 무한 루프가 발생하거나 마지막 if 문으로 점프하게 됩니다. if [ $timer -eq 90] ; then... , 또는 if/elif의 어떤 부분도 전혀 실행하지 않습니다.

이것은 내 현재 코드입니다.

retry=0
curl -K $conf/appdCurlConfig $prodc $base1d $base3d $base1w $base2w -o $prodCurl -o $base1dCurl -o $base3dCurl -o $base1wCurl -o $base2wCurl && cpid=`ps -o etime= -p $!`
SECONDS=0
timer=$(( cpid+$SECONDS ))

if [ $retry -lt 3 ] ; then
  if [ $timer -eq 45 ] ; then
    echo -e "\e[93mYour request is taking longer than expected, but is still processing\e[m"
  fi
  if [ $timer -eq 55 ] ; then
    echo -e "\e[93mYour request is still processing\e[m"
  fi
  if [ $timer -eq 65 ] ; then
    echo -e "\e[93mYour request is still processing\e[m"
  fi
  if [ $timer -eq 75 ] ; then
    echo -e "\e[93mYour request is still processing\e[m"
  fi
  if [ $timer -eq 85 ] ; then
    echo -e "\e[93mYour request is still processing\e[m"
  fi
  if [ $timer -ge 90 ] ; then
    echo -e "\e[31mWe are experiencing some technical difficulty, or it has taken over 90 seconds to reach $appset; restarting your request\e[m"
    run $param1 $param2 $param3
    let retry++
  else
    if [ $retry -eq 3 ] ; then
      echo -e "\e[93mWe are unable to reach $appset at this time, please try again in 5 minutes"
      echo -e "If you keep getting this error message, please contact the system administrator\e[m"
      exit 2
    fi
  fi
fi

또한 싱글을 사용하여 백그라운드에서 실행해 보았고, 아래를 자체 함수로 만들고 and &를 사용하여 호출해 보았고, 아래를 or가 되도록 래핑해 보았습니다.&&&$(below code)& $(code)&& $(code)

ctimer() {
cpid=$(ps -o etime= -p $!)
SECONDS=0
timer=$(( cpid+$SECONDS ))
if [ $retry -lt 3 ] ; then
  if [ $timer -eq 45 ] ; then
    echo -e "\e[93mYour request is taking longer than expected, but is still processing\e[m"
  fi
  if [ $timer -eq 55 ] ; then
  echo -e "\e[93mYour request is still processing\e[m"
  fi
  if [ $timer -eq 65 ] ; then
  echo -e "\e[93mYour request is still processing\e[m"
  fi
  if [ $timer -eq 75 ] ; then
  echo -e "\e[93mYour request is still processing\e[m"
  fi
  if [ $timer -eq 85 ] ; then
  echo -e "\e[93mYour request is still processing\e[m"
  fi
  if [ $timer -ge 90 ] ; then
    echo -e "\e[31mWe are experiencing some technical difficulty, or it has taken over 90 seconds to reach $appset; restarting your request\e[m"
    run $param1 $param2 $param3
    let retry++
  else
    if [ $retry -eq 3 ] ; then
      echo -e "\e[93mWe are unable to reach $appset at this time, please try again in 5 minutes"
      echo -e "If you keep getting this error message, please contact the system administrator\e[m"
      exit 2
    fi
  fi
fi
}

일부 변수를 명확히 하기 위해 하나 $conf/는 경로 변수이고, $prodc모두 $base*는 URL 변수이고, 다른 변수는 설명이 필요하며 $appset컬의 내부 응용 프로그램입니다. run는 이 스크립트의 함수이고 $param*는 사용자의 초기 입력입니다.

내가 뭔가를 놓치고 있는 걸까요, 아니면 불가능한 걸까요? kill컬을 다시 실행하기 전에 전화를 한 번 더 해야 합니까? 당신의 도움을 주셔서 감사합니다.

답변1

당신은 이것을 지나치게 생각하고 있으며 일부 내장 기능이 무엇인지 알지 못할 수도 있습니다 bash(지정하지 않았으므로 쉘이 있다고 가정하겠습니다).

retries=0
timeout=90
duration=0
complete=0
maxretries=3
while [[ 0 -eq "$complete" ]]; do
    curl -K $conf/appdCurlConfig $prodc $base1d $base3d $base1w $base2w -o $prodCurl -o $base1dCurl -o $base3dCurl -o $base1wCurl -o $base2wCurl &
    curlpid=$! # capture PID of curl command
    while [[ "$timeout" -gt "$duration" ]] && kill -0 $curlpid 2> /dev/null; do
        sleep 1
        duration=$((duration+1))
        case $duration in
            3) 
                echo "It's taking a bit longer.."
                ;;
            30|45|75)
                echo "It's taking a real long time but we'll keep waiting"
                ;;
            85)
                echo "We're about to give up"
                ;;
            $timeout)
                echo "We're giving up."
                kill -TERM $curlpid
                retries=$((retries+1))
                if [[ "$retries" -ge "$maxretries" ]]; then
                    complete=1
                fi
                ;;
        esac
    done
    if wait $curlpid; then
        complete=1 # curl returned non-error; we're done!
    fi
done

kill -0빈 신호가 전송되면 프로세스에 실제로 영향을 주지 않고 실제로 존재하는지 확인하는 데 사용할 수 있습니다. 쉘은 백그라운드 작업의 PID를 캡처합니다 $!. if..elif사다리는 명령문으로 축소할 수 있는 방법에 대한 교과서적인 예입니다 case..esac.

답변2

진행 상황 정보가 그다지 좋지 않다는 점을 인정할 수 있는 경우:

parallel --retries 3 --timeout 10 curl ::: url &&
  echo success ||
  echo failed

예:

$ parallel --retries 3 --timeout 10 curl ::: 10.1.1.1 &&
    echo success ||
    echo failed
parallel: Warning: This job was killed because it timed out:
parallel: Warning: curl 10.1.1.1
parallel: Warning: This job was killed because it timed out:
parallel: Warning: curl 10.1.1.1
parallel: Warning: This job was killed because it timed out:
parallel: Warning: curl 10.1.1.1
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:10 --:--:--     0failed

관련 정보