无法捕获已经背景的子shell的输出

时间:2015-02-23 17:06:33

标签: bash parallel-processing background-process

试图做一个简单的" bash中的并行函数。目前的问题是当捕获输出的线路背景时,输出会丢失。如果该行没有后台运行,则输出被捕获得很好,但这当然会破坏该功能的目的。

  #!/usr/bin/env bash

  cluster="${1:-web100s}"
  hosts=($(inventory.pl bash "$cluster" | sort -V))
  cmds="${2:-uptime}"

  parallel=10
  cx=0
  total=0
  for host in "${hosts[@]}"; do
    output[$total]=$(echo -en "$host: ")
    echo "${output[$total]}"
    output[$total]+=$(ssh -o ConnectTimeout=5 "$host" "$cmds") &
    cx=$((cx + 1))
    total=$((total + 1))
    if [[ $cx -gt $parallel ]]; then
      wait >&/dev/null
      cx=0
    fi
  done

  echo -en "***** DONE *****\n     Results\n"

  for ((i=0; i<= $total; i++)); do
    echo "${output[$i]}"
  done

2 个答案:

答案 0 :(得分:1)

那是因为你的命令(赋值)是在子shell中运行的,所以这个赋值不能影响父shell。这归结为:

a=something
a='hello senorsmile' &
echo "$a"

你能猜出输出是什么吗?当然,输出是

something

而不是hello senorsmile。子shell与父shell通信的唯一方法是以一种或另一种形式使用IPC(进程间通信)。我没有任何提议的解决方案,我只是试图解释它失败的原因。

如果你想到它,它应该是有道理的。你怎么看待这个?

a=$( echo a; sleep 1000000000; echo b ) &

该命令立即返回(分叉后)......但输出仅在......超过31年才能完全可用。

答案 1 :(得分:0)

以这种方式在后台分配shell变量实际上毫无意义。 Bash确实内置了协同处理功能,适用于您:

http://www.gnu.org/software/bash/manual/bashref.html#Coprocesses