如何从shell脚本运行并发后台进程?

时间:2015-09-21 19:42:58

标签: bash

我尝试了以下内容:

#!/bin/bash

while read device; do
        name=$(echo "$device" | awk '{ print $1 }')
        ip=$(echo "$device" | awk '{ print $2 }')
        while read creds; do
                community=$(echo "$creds" | awk '{ print $1 }')
                version=$(echo "$creds" | awk '{ print $2 }')
                mkdir -p walks/$name;
                `echo -e "snmpwalk -v$version -c \x27$community\x27 $ip system > walks/$name/$community-$version.txt
        done < <(##MySQL query that returns tuples in form: (snmp_ro,(1,2c,3))##")
done < <(cat devices.txt)
exit 0

这是为了找到snmp字符串和每个设备的版本。

devices.txt是表单中的设备列表:hostname ip

它没有创建文件:walking / $ name / $ community- $ version.txt,它似乎只能一次遍历1个步行,这是我不想要的。< / p>

1 个答案:

答案 0 :(得分:2)

使用&将您希望背景的内容放入背景中。

pids=( )
while read -r -u 3 name ip _; do
  while read -r -u 4 community version _; do
    mkdir -p "walks/$name"
    snmpwalk -v"$version" -c "$community" "$ip" system \
      </dev/null >"walks/$name/$community-$version.txt" & pids+=( "$!" )
  done 4< <(: get data for "$name" and "$ip")
done 3<devices.txt
wait "${pids[@]}"

其他注意事项:

  • read已经可以将字段拆分为自己的变量;使用awk这是愚蠢的。
  • _中的read -r foo bar _确保如果输入文件中存在两列以上,则第三列及以后的列将被丢弃(实际上,放入名为_的变量中,但是这被视为按惯例丢弃)而不是附加到bar
  • 养成引用扩展的习惯,除非你有特别和令人信服的理由不这样做;否则,你会得到字符串分割和字符串内容的全局扩展。
  • 此示例将每个输入流放在其自己的文件描述符上,并将每个read重定向到其自己的FD。这可以防止循环中的任何其他内容使用stdin。