shell bash脚本中的多线程多行代码

lc8prwob  于 2023-02-09  发布在  Shell
关注(0)|答案(2)|浏览(162)

我所拥有的脚本的一部分遍历LAN中的所有IP地址,并检查关联的FQDN。

while [[ $ws -le $total_ip ]]; do
    ip="${ip_range}.${ws}"
    machine=$(timeout 0.3s python3 -c "import socket; print(socket.getfqdn('$ip'))")
    if[[ "$machine" = "$myMachine" ]]; then 
        my_ip=$ip
        break
    fi
done

这个命令现在就可以运行,但是需要很长时间才能完成,我在python命令前面添加了一个timeout命令,以确保它不会持续超过0.3秒,但是这仍然是相当长的时间。
我想知道我是否可以线程化这段代码来加速这个过程:

machine=$(timeout 0.3s python3 -c "import socket; print(socket.getfqdn('$ip'))")
if[[ "$machine" = "$myMachine" ]]; then 
    my_ip=$ip
    break
fi

但是,它需要是原生的bash,因为我不想在其他计算机上运行它,而不必安装任何其他工具。

jv2fixgn

jv2fixgn1#

一个简单的python解决方案。它传递机器名和要检查的IP范围,如果找到就打印IP,如果没有找到给定机器名的IP就设置一个非零退出代码。如果性能是你的目标,总的运行时间只有几毫秒。

#!/bin/bash
myMachine=$1
ip_range=$2

if my_ip=$( python3 -c '
import sys
import socket
my_machine = sys.argv[1]
for ip in sys.argv[2:]:
  if socket.getfqdn(ip) == my_machine:
    print(ip)
    sys.exit(0)
sys.exit(1)
' "$myMachine" "$ip_range".{0..255} ) ; then
  echo "$myMachine IP: $my_ip"
else
  echo "IP for $myMachine not found."
fi

bash示例中的超时并没有显著提高性能,因为python的每个示例可能都运行得非常快。性能问题是产生大量子进程的结果-fork是一个开销非常大的系统调用,并且您通过在每次迭代中调用python3的新示例来强制bash重复调用它。即使添加“线程”也不会显著提高性能,因为(再一次)瓶颈不是python太慢,而是创建python的示例是一个缓慢的操作,试图用多线程解决这个问题只会导致代码非常混乱和容易出错,而性能的提高微乎其微。
这类问题的解决方案通常是减少创建的子进程的数量,这就是为什么我建议只调用python3一次,让它来完成繁重的工作。

yuvru6vn

yuvru6vn2#

According to the Bash documentation您可以将代码 Package 到{}中进行分组。如果将&放在该组后面,则它将异步执行。要等待所有子进程完成,请使用wait
示例:

{
    echo "foo"
    sleep 1
    echo "bar"
} &
echo "baz"
wait

将输出:

baz
foo
# and after one second
bar

可以在here中找到有关bash作业控制的更多信息。

相关问题