如何同时运行但如果失败则退出1?

时间:2017-06-13 18:29:09

标签: bash

我有以下sh文件:

#!/usr/bin/env bash
ecs deploy [some not relevant stuff here] & \
ecs deploy [some not relevant stuff here] & \
ecs deploy [some not relevant stuff here] & \
ecs deploy [some not relevant stuff here] & \
ecs deploy [some not relevant stuff here] & \
ecs deploy [some not relevant stuff here]

这部分起作用,因为它确实同时运行部署命令,但是如果有任何部署,我必须返回适当的退出代码。退出代码大于0。

有没有办法用bash来实现这个目标?如果可能,不使用任何tmp文件,只需要变量。

4 个答案:

答案 0 :(得分:4)

不清楚为什么你想要最大的退出代码;如果没有进一步的信息,我会假设您只是想在其他进程的任何具有非零退出代码时返回非零退出代码。

ecs deploy [some not relevant stuff here] & pids+=($!)
ecs deploy [some not relevant stuff here] & pids+=($!)
ecs deploy [some not relevant stuff here] & pids+=($!)
ecs deploy [some not relevant stuff here] & pids+=($!)
ecs deploy [some not relevant stuff here] & pids+=($!)
ecs deploy [some not relevant stuff here] & pids+=($!)

rv=0
for pid in "${pids[@]}"; do
  wait "$pid" || rv=1
done
exit "$rv"

答案 1 :(得分:1)

首先关于管理子进程我建议切换到python,因为它有一些模块比用bash编写的任何东西做得更好,正如所说的那样。

这里有很多好的答案,但我就是这样做的。

#!/bin/bash

sleep 4; /bin/false &
pids+=("$!")
sleep 5 &
pids+=("$!")
sleep 5 &
pids+=("$!")
sleep 5 &
pids+=("$!")
sleep 5 &
pids+=("$!")

declare -A -g exit_tracker=()

rc=0
for pid in ${pids[@]}; do
    wait $pid
    if (( $? == 1 )); then
        exit_tracker[$pid]="FAIL"
    else
        exit_tracker[$pid]="SUCCESS"
    fi
done

for key in ${!exit_tracker[@]}; do
    printf "%s\n" "$key PID STATUS: ${exit_tracker[$key]}"
done

如果您想要获得CRAZIER!您可以使用关联数组命名每个返回代码,并具体找出哪个pid失败。您可以在看到sleep_fail,sleep_pass_1等的地方补充自己的名字......

#!/bin/bash

declare -A -g pid_names=()

sleep 4; /bin/false &
pid_names["sleep_fail"]="$!"
sleep 5 &
pid_names["sleep_pass_1"]="$!"
sleep 5 &
pid_names["sleep_pass_2"]="$!"
sleep 5 &
pid_names["sleep_pass_3"]="$!"
sleep 5 &
pid_names["sleep_pass_4"]="$!"

declare -A -g exit_tracker=()

rc=0
for pid in ${!pid_names[@]}; do
    wait ${pid_names[$pid]}
    if (( $? == 1 )); then
        exit_tracker[$pid]="FAIL"
    else
        exit_tracker[$pid]="SUCCESS"
    fi
done

for key in ${!exit_tracker[@]}; do
    printf "%s\n" "$key PID STATUS: ${exit_tracker[$key]}"
done

上面的输出如下所示:

dumbledore@ansible1a [OPS]:~ > bash test.sh
sleep_fail PID STATUS: FAIL
sleep_pass_4 PID STATUS: SUCCESS
sleep_pass_2 PID STATUS: SUCCESS
sleep_pass_3 PID STATUS: SUCCESS
sleep_pass_1 PID STATUS: SUCCESS

答案 2 :(得分:0)

# note normal single quotes in following line
CMD='curl -I shoudfail.com'

# run the command, and log it IF IT FAILS
( $CMD || echo $CMD >> tmpout ) &

# rinse, lather, repeat
CMD='curl -I somecmdthatwillfail.com'

# run the command, and log it IF IT FAILS
( $CMD || echo $CMD >> tmpout ) &

...

while [ ! -z `jobs` ]  
do
   sleep 5
done

如果使用readline来填充CMD而不是代码中的文字,那么您可以使用一次迭代的输出作为下一次迭代的输入。

答案 3 :(得分:0)

#!/usr/bin/env bash
# This array will store process ID's of background processes
declare -a pid

# Run curl and save add its pid to array
curl -I shoudfail.com; echo $? >> tmpout &
pid+=( $! )

# Run another curl and save add its pid to array
curl -I somecmdthatwillfail.com a; echo $? >> tmpout & \
pid+=( $! )

# Run a third curl and save add its pid to array
curl -I google.com; echo $? >> tmpout;
pid+=( $! )

# Wait for all background processes to stop
wait

# Loop through array of pids
for proc in "${pid[@]}"; do
    # Get return value of process from wait
    wait "$proc"
    retval=$?

    # Replace maxret if the return value is larger
    [ "$retval" -gt "$maxret" ] && maxret="$retval"

done

echo "$maxret"