假设我有一个Bash脚本,它接受一个参数(即端口号),并用任一结果执行一些逻辑
找到导致结果2的参数的一种方法是在参数的可能值上运行脚本循环,但这需要N秒来查找参数。假设输出是一致的(例如,如果多个实例导致结果2,则它们的输出消息是相同的)。
是否有办法在参数的每个可能值的同时(在合理的毫秒内)运行Bash脚本的N个实例,并从最快完成的实例获取输出消息?这将导致输出不到1秒。
答案 0 :(得分:0)
要允许复制器,让我们首先创建一个与您的命令相似的功能:
try_or_wait() {
local argument=$1 # doesn't really matter for our purposes
if (( RANDOM % 10 == 0 )); then # 10% return a result immediately
if (( (RANDOM + argument) % 2 == 0 )); then
echo ON
else
echo OFF
fi
else # 90% hang, and then fail
sleep 10
exit 1
fi
}
......那么,我们怎么能用呢?
declare -a pids=( )
mkfifo out.fifo
# start 20 processes, passing your port number to each
for ((i=0; i<20; ++i)); do
try_or_wait "$1" >out.fifo & pids+=( "$!" )
done
# read one result
read result <out.fifo
# kill all the remaining children
kill "${pids[@]}"
echo "Got the result: $result"
不是这是唯一的方法。让GNU xargs
为您完成产生子进程的工作:
export -f try_or_wait # export shell functions so child processes can run it
read -r result < <(
for ((i=0; i<20; ++i)); do
printf '%s\0' "$1"
done | xargs -0 -n 1 -P 20 bash -c 'try_or_wait "$@"' _
)
请注意,上述内容是安全的,因为每个实例都会同时执行一次写入 - 一个echo
,足够短以使整个输出适合单个系统调用。如果程序的每个实例都有足够的输出来要求多个系统调用(或输出拆分多次写入),则可能需要一个可以为您执行整理的工具。