0

xargs timeout重试脚本编写完整教程:3个实战技巧让批量任务超时自动重试

2026.07.01 | youres | 68次围观

鍓嶈█

鐢▁args鍋氬苟琛屾壒閲忓鐞嗘椂锛屾渶澶寸柤鐨勪笉鏄换鍔″け璐ワ紝鑰屾槸浠诲姟鍗℃鍦╰imeout涓?/strong>鈥斺€旇繘绋嬫棤澹版棤鎭湴娑堝け锛屼綘鍗磋繛閲嶈瘯鐨勬満浼氶兘娌℃湁銆傛湰鏂囩敤3涓畬鏁寸殑瀹炴垬鑴氭湰锛屽甫浣犱粠闆舵惌寤轰竴濂?strong>xargs timeout閲嶈瘯鏈哄埗锛岃姣忎竴涓壒閲忎换鍔¢兘鑳藉湪瓒呮椂鍚庤嚜鍔ㄦ仮澶嶃€?/p>

涓€銆佷负浠€涔坸args骞惰浠诲姟闇€瑕乼imeout閲嶈瘯鏈哄埗

xargs -P 骞惰鍚姩瀛愯繘绋嬫椂锛屽鏋滄煇涓瓙杩涚▼鍥犱负缃戠粶瓒呮椂銆佽祫婧愮珵浜夋垨閫昏緫姝婚攣鑰屽崱浣忥紝xargs 鏈韩骞朵笉浼氫富鍔ㄦ竻鐞嗗畠銆傜粨鏋滃氨鏄細

  • 骞惰妲戒綅琚崰婊★紝鍚庣画浠诲姟鏃犳硶鍚姩
  • CPU鍜屽唴瀛樿鍍靛案杩涚▼鎮勬倓鍚冩帀
  • 鏁翠釜鎵归噺浠诲姟 silently hangs锛屼綘鍙兘鎵嬪姩 kill

鏍稿績瑙f硶锛氱敤 timeout 鍛戒护缁欐瘡涓瓙杩涚▼璁句竴涓?strong>纭秴鏃朵笂闄?/strong>锛屽啀鐢ㄩ€€鍑虹爜鍒ゆ柇鏄惁闇€瑕侀噸璇曘€?/p>

浜屻€乼imeout鍛戒护涓巟args鐨勯厤鍚堝師鐞?/h2>

2.1 timeout鐨勫熀纭€鐢ㄦ硶

timeout [閫夐」] 鏃堕暱 鍛戒护 [鍙傛暟]...

鍏抽敭鍙傛暟锛?/p>

  • --signal=SIGTERM锛堥粯璁わ級锛氳秴鏃跺悗鍏堝彂SIGTERM锛屽瓙杩涚▼鍙崟鑾峰仛娓呯悊
  • --kill-after=5s锛氬鏋淪IGTERM鍚庤繘绋嬭繕娲荤潃锛?绉掑悗鍙慡IGKILL寮哄埗鏀跺壊
  • -- foreground锛氬湪鍓嶅彴杩愯锛坸args鍦烘櫙涓嬪父鐢級

2.2 timeout鐨勯€€鍑虹爜瑙勫垯锛堟牳蹇冪煡璇嗭級

閫€鍑虹爜鍚箟xargs鍦烘櫙涓嬬殑澶勭悊寤鸿
0鍛戒护姝e父瀹屾垚鏃犻渶閲嶈瘯锛岀户缁笅涓€涓?/td>
124鍛戒护琚玹imeout寮哄埗缁堟闇€瑕侀噸璇?/strong>锛屽缓璁寚鏁伴€€閬?/td>
125timeout鑷韩澶辫触锛堝鍛戒护涓嶅瓨鍦級璁板綍閿欒锛岃烦杩囪浠诲姟
126鍛戒护涓嶅彲鎵ц妫€鏌ユ潈闄愶紝璺宠繃
127鍛戒护鏈壘鍒?/td>鐜妫€鏌ワ紝璺宠繃
鍏朵粬闈為浂瀛愬懡浠よ嚜韬€€鍑虹爜鏍规嵁涓氬姟閫昏緫鍐冲畾鏄惁閲嶈瘯

涓夈€佸疄鎴樿剼鏈竴锛氬熀纭€鐗堚€斺€旇秴鏃惰嚜鍔ㄩ噸璇?娆?/h2>

鏈€瀹炵敤鐨勮捣姝ユ柟妗堬紝閫傚悎澶у鏁版壒閲忓鐞嗗満鏅€?/p>

#!/bin/bash
# xargs-timeout-retry-basic.sh
# 鐢ㄦ硶锛歝at url-list.txt | ./xargs-timeout-retry-basic.sh

MAX_RETRIES=3
TIMEOUT_DURATION="30s"

retry_handler() {
    local task="$1"
    local attempt=0
    local exit_code
    
    while [ $attempt -lt $MAX_RETRIES ]; do
        attempt=$((attempt + 1))
        echo "[$(date '+%H:%M:%S')] 灏濊瘯 #$attempt: $task" >&2
        
        timeout --signal=SIGTERM --kill-after=5s $TIMEOUT_DURATION \n            curl -s -o /dev/null -w "%{http_code}" "$task"
        exit_code=$?
        
        if [ $exit_code -eq 0 ]; then
            echo "[$(date '+%H:%M:%S')] 鎴愬姛: $task" >&2
            echo "OK: $task"
            return 0
        elif [ $exit_code -eq 124 ]; then
            echo "[$(date '+%H:%M:%S')] 瓒呮椂锛堥€€鍑虹爜124锛夛紝绛夊緟2绉掑悗閲嶈瘯..." >&2
            sleep 2
        else
            echo "[$(date '+%H:%M:%S')] 澶辫触锛堥€€鍑虹爜$exit_code锛夛紝閲嶈瘯..." >&2
            sleep 1
        fi
    done
    
    echo "[$(date '+%H:%M:%S')] 鏀惧純: $task锛堝凡閲嶈瘯$MAX_RETRIES娆★級" >&2
    echo "FAIL: $task"
    return 1
}

export -f retry_handler
export MAX_RETRIES TIMEOUT_DURATION

xargs -P 8 -I {} bash -c 'retry_handler "{}"'

鍥涖€佸疄鎴樿剼鏈簩锛氳繘闃剁増鈥斺€旀寚鏁伴€€閬?鏃ュ織璁板綍

鐢熶骇鐜鎺ㄨ崘鏂规锛岄伩鍏嶉噸璇曢鏆村鐩爣鏈嶅姟閫犳垚浜屾浼ゅ銆?/p>

#!/bin/bash
# xargs-timeout-retry-advanced.sh
# 鐗规€э細鎸囨暟閫€閬裤€丆SV鏃ュ織銆佸け璐ョ巼缁熻

LOG_FILE="xargs-retry-$(date '+%Y%m%d').csv"
TIMEOUT_DURATION="45s"
MAX_RETRIES=5

# 鍒濆鍖栨棩蹇?echo "timestamp,task,attempt,exit_code,status" > "$LOG_FILE"

retry_with_backoff() {
    local task="$1"
    local attempt=0
    local exit_code
    local wait_time=1
    
    while [ $attempt -lt $MAX_RETRIES ]; do
        attempt=$((attempt + 1))
        
        timeout --signal=SIGTERM --kill-after=10s $TIMEOUT_DURATION \n            your-command-here "$task" > /dev/null 2>&1
        exit_code=$?
        
        if [ $exit_code -eq 0 ]; then
            echo "$(date '+%Y-%m-%d %H:%M:%S'),$task,$attempt,$exit_code,SUCCESS" >> "$LOG_FILE"
            echo "OK: $task"
            return 0
        elif [ $exit_code -eq 124 ]; then
            echo "$(date '+%Y-%m-%d %H:%M:%S'),$task,$attempt,$exit_code,TIMEOUT" >> "$LOG_FILE"
            echo "[閲嶈瘯 #$attempt] 瓒呮椂锛岀瓑寰?${wait_time}s..." >&2
            sleep $wait_time
            wait_time=$((wait_time * 2))  # 鎸囨暟閫€閬匡細1s,2s,4s,8s...
        else
            echo "$(date '+%Y-%m-%d %H:%M:%S'),$task,$attempt,$exit_code,ERROR" >> "$LOG_FILE"
            sleep 1
        fi
    done
    
    echo "$(date '+%Y-%m-%d %H:%M:%S'),$task,$MAX_RETRIES,,FAILED" >> "$LOG_FILE"
    echo "FAIL: $task" >&2
    return 1
}

export -f retry_with_backoff
export LOG_FILE TIMEOUT_DURATION MAX_RETRIES

xargs -P 4 -I {} bash -c 'retry_with_backoff "{}"'

浜斻€佸疄鎴樿剼鏈笁锛氱敓浜х骇鈥斺€斿苟鍙戞帶鍒?閫€鍑虹爜鏀堕泦

閫傚悎闇€瑕佺簿纭帉鎻℃瘡涓换鍔℃渶缁堢姸鎬佺殑鍦烘櫙锛堝鎵归噺鏁版嵁鍚屾锛夈€?/p>

#!/bin/bash
# xargs-timeout-retry-production.sh
# 鐗规€э細骞跺彂鏁板姩鎬佹帶鍒躲€侀€€鍑虹爜姹囨€汇€佺粨鏋滃垎绫昏緭鍑?
TIMEOUT_DURATION="60s"
MAX_RETRIES=3
MAX_PARALLEL=6

SUCCESS_FILE="/tmp/xargs-success-$$.txt"
TIMEOUT_FILE="/tmp/xargs-timeout-$$.txt"
FAILED_FILE="/tmp/xargs-failed-$$.txt"

# 娓呯悊鍑芥暟
cleanup() {
    echo "=== 鎵ц缁撴灉姹囨€?==="
    echo "鎴愬姛: $(wc -l < $SUCCESS_FILE) 涓?
    echo "瓒呮椂: $(wc -l < $TIMEOUT_FILE) 涓?
    echo "澶辫触: $(wc -l < $FAILED_FILE) 涓?
    rm -f $SUCCESS_FILE $TIMEOUT_FILE $FAILED_FILE
}
trap cleanup EXIT

: > $SUCCESS_FILE
: > $TIMEOUT_FILE
: > $FAILED_FILE

retry_production() {
    local task="$1"
    local attempt=0
    local exit_code
    
    while [ $attempt -lt $MAX_RETRIES ]; do
        attempt=$((attempt + 1))
        
        timeout --signal=SIGTERM $TIMEOUT_DURATION \n            your-command-here "$task"
        exit_code=$?
        
        case $exit_code in
            0)
                echo "$task" >> $SUCCESS_FILE
                echo "OK: $task"
                return 0
                ;;
            124)
                if [ $attempt -lt $MAX_RETRIES ]; then
                    sleep $((attempt * 2))
                    continue
                else
                    echo "$task" >> $TIMEOUT_FILE
                    echo "TIMEOUT: $task"
                    return 124
                fi
                ;;
            *)
                if [ $attempt -lt $MAX_RETRIES ]; then
                    sleep 1
                    continue
                else
                    echo "$task" >> $FAILED_FILE
                    echo "ERROR($exit_code): $task"
                    return $exit_code
                fi
                ;;
        esac
    done
}

export -f retry_production
export MAX_RETRIES TIMEOUT_DURATION SUCCESS_FILE TIMEOUT_FILE FAILED_FILE

xargs -P $MAX_PARALLEL -I {} bash -c 'retry_production "{}"'

鍏€?涓剼鏈殑閫夊瀷寤鸿

鑴氭湰鐗堟湰閫傜敤鍦烘櫙鏍稿績浼樺娍
鍩虹鐗?/td>绠€鍗曟壒閲忎换鍔°€佸揩閫熼獙璇?/td>浠g爜鏈€鐭紝5鍒嗛挓涓婃墜
杩涢樁鐗?/td>鐢熶骇鐜銆侀渶瑕佸璁℃棩蹇?/td>鎸囨暟閫€閬夸繚鎶ょ洰鏍囨湇鍔?/td>
鐢熶骇绾?/td>澶ц妯℃壒閲忓鐞嗐€侀渶瑕佺簿纭姸鎬佺粺璁?/td>閫€鍑虹爜鍒嗙被姹囨€伙紝渚夸簬鍚庣画鑷姩鍖栧鐞?/td>

涓冦€佸父瑙佸潙鐐逛笌鎺掓煡鏂规硶

  • 鍧戜竴锛歵imeout鍚庤繘绋嬫湭鐪熸閫€鍑?/strong>鈥斺€斿姞涓?--kill-after 鍙傛暟锛岀‘淇漇IGKILL鍏滃簳
  • 鍧戜簩锛歺args骞惰鏁拌澶ぇ瀵艰嚧绯荤粺璐熻浇鏆村鈥斺€斿缓璁?-P 鍊间笉瓒呰繃CPU鏍稿績鏁扮殑2鍊?/li>
  • 鍧戜笁锛氶噸璇曟椂鏈仛閫€閬匡紝瀵艰嚧鐩爣鏈嶅姟琚埛鐖?/strong>鈥斺€斿姟蹇呬娇鐢ㄦ寚鏁伴€€閬挎垨闅忔満鎶栧姩
  • 鍧戝洓锛氬拷鐣ヤ簡timeout閫€鍑虹爜124鐨勫垽鏂?/strong>鈥斺€?24鏄秴鏃朵笓灞為€€鍑虹爜锛屼笉瑕佸拰涓€鑸敊璇贩涓轰竴璋?/li>

鍏€佺浉鍏虫枃绔犳帹鑽?/h2>

鎬荤粨

鎶?timeout 鍜?xargs 閰嶅悎浣跨敤锛屾牳蹇冨氨鏄笁浠朵簨锛?strong>璁捐秴鏃躲€佸垽閫€鍑虹爜銆佸仛閲嶈瘯銆傛湰鏂囩殑涓変釜鑴氭湰浠庣畝鍗曞埌鐢熶骇绾э紝瑕嗙洊浜嗙粷澶у鏁颁娇鐢ㄥ満鏅€傚缓璁厛鍦ㄦ祴璇曠幆澧冭窇閫氬熀纭€鐗堬紝鍐嶉€愭鍗囩骇鍒板甫鏃ュ織鍜岄€€閬跨殑杩涢樁鐗堟湰銆?/p>

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论