【问题标题】:How to add threading to the bash script?如何在 bash 脚本中添加线程?
【发布时间】:2017-05-04 13:45:03
【问题描述】:
#!/bin/bash
cat input.txt | while read ips
do
    cmd="$(snmpwalk -v2c -c abc@123 $ips sysUpTimeInstance)"
    echo "$ips ---> $cmd"
    echo "$ips $cmd" >> out_uptime.txt
done

如何向这个 bash 脚本添加线程,我有大约 80000 个输入并且需要很多时间?

【问题讨论】:

  • 使用处理多个IP的程序而不是调用snmpwalk 80,000次。
  • @chepner,显然 OP 不知道存在替代品。替代程序的名称比暗示未命名的程序更有帮助。
  • SNMP 是一种协议;使用 SNMP 库的自定义程序更有可能比尝试找到适合用例的其他程序更有用。关键是,多次重新运行一次性程序几乎从来都不是正确的方法。

标签: linux multithreading bash centos snmp


【解决方案1】:
  1. 简单的方法。假设输出的顺序不重要,并且snmpwalk 的输出没有意义如果它应该失败,在每个末尾添加一个&&后台的命令,除了最后一个应该有 & 的命令:

    #!/bin/bash
    while read ips
    do
        cmd="$(nice snmpwalk -v2c -c abc@123 $ips sysUpTimeInstance)" &&
        echo "$ips ---> $cmd" &&
        echo "$ips $cmd" >> out_uptime.txt &
    done < input.txt
    
  2. 不那么简单。如果snmpwalk 可能失败,并且还需要该输出,请丢失&amp;&amp; 并用大括号{}&amp; 将代码括起来。要将附加的输出重定向到包含标准错误,请使用&amp;&gt;&gt;:

    #!/bin/bash
    while read ips
    do  {
        cmd="$(nice snmpwalk -v2c -c abc@123 $ips sysUpTimeInstance)"
        echo "$ips ---> $cmd"
        echo "$ips $cmd" &>> out_uptime.txt
        } &
    done < input.txt
    

    大括号可以包含更复杂的if ... then ... else ... fi 语句,所有这些语句都将是背景的。


对于那些没有复杂的snmpwalk 命令来测试的人,这里有一个类似的循环,它打印一到五个,但在echo 命令之间随机休眠:

for f in {1..5}; do
    RANDOM=$f && 
    sleep $((RANDOM/6000)) &&
    echo $f &
done 2> /dev/null | cat

每次输出都相同,(删除RANDOM=$f &amp;&amp; 以获取不同的输出),并且需要三秒钟才能运行:

2
4
1
3
5

比较没有 &amp;&amp;s 和 &amp; 的代码:

for f in {1..5}; do
    RANDOM=$f
    sleep $((RANDOM/6000))
    echo $f
done 2> /dev/null | cat

运行时,代码需要 7 秒才能运行,输出如下:

1
2
3
4
5

【讨论】:

  • 它运行良好,但占用了全部 cpu 利用率,任何方法可以将其减少到更少,或者您可以通过代码控制 cpu utiiz
  • @Zeal,有点固定。见man nice,也见Limiting processes to not exceed more than 10% of CPU usage
  • 谢谢!!如果你知道它是如何工作的,Linux 就非常好。我将探索漂亮的命令和您提供的链接。
【解决方案2】:

您可以通过&amp;将任务发送到后台。如果您打算等待所有这些都完成,您可以使用wait 命令:

process_to_background &
echo Processing ...
wait
echo Done

如果您想等待一个(或几个)特定任务,您可以在后台启动给定任务的 pid

important_process_to_background &
important_pid=$!
while i in {1..10}; do
    less_important_process_to_background $i &
done

wait $important_pid
echo Important task finished

wait
echo All tasks finished

请注意:后台进程可能会弄乱输出,因为它们将异步运行。您可能想使用 命名管道 来收集它们的输出。

【讨论】:

  • 我是 bash 和 linux 新手,您是否可以修改上述脚本以包含多处理而不会丢失输出?
猜你喜欢
  • 2011-09-14
  • 1970-01-01
  • 2019-05-23
  • 2019-03-12
  • 2022-01-20
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多