多线程执行多行代码在bash脚本中。

huangapple go评论58阅读模式
英文:

Multiple threading multiple lines of code in bash scripts

问题

以下是代码部分的翻译:

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

请注意,我已经去掉了HTML编码,以便代码更容易阅读。

英文:

Part of a script I have goes through all the IP addresses in the LAN, and checks the associated 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

This works right now, but takes quite a long time to complete.
I added a timeout command in front of the python command to make sure it doesn't go on for more than 0.3 seconds, but that still is quite long.

I want to know if I can thread this piece of code to speed up the process:

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

However, it needs to be native bash, because I wan't to run this on other computers without having to install any additional tools.

答案1

得分: 1

以下是翻译好的代码部分:

#!/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
英文:

A simple mostly-python solution. This passes the machine name and a range of IPs to check, prints the IP if found, and sets a non-zero exit code if it doesn't find an IP for the given machine name. The total runtime is just a few milliseconds if performance is your goal.

#!/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

The timeout in your bash example does not improve performance much if at all because each individual instance of python is probably running very fast. Your performance issues are a result of spawning lots of child processes - fork is a very expensive system call, and you're forcing bash to call it repeatedly by invoking a new instance of python3 on every iteration. Even adding "threading" would not improve performance much, because (again) the bottleneck is not that python is too slow, it's that creating an instance of python is a slow operation. Trying to solve the problem with multithreading is just going to result in very messy and error-prone code with minimal gains in performance.

The solution to this type of problem is normally to reduce the number of child processes you create, which is why I recommend calling python3 only once and letting it do the heavy lifting.

答案2

得分: 1

根据Bash文档,您可以将您的代码放在{}中进行分组。如果在这个组后面加上&,它将被异步执行。要等待所有子进程完成,使用wait命令。

示例:

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

将输出:

baz
foo
# 一秒后
bar

有关Bash作业控制的更多信息可以在这里找到。

英文:

According to the Bash documentation you can wrap your code into {} to group it. If a & is put behind this group, it will be executed asynchronously. to wait for all subprocesses to finish, use wait

Example:

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

Will output:

baz
foo
# and after one second
bar

more information on bash job control can be found here.

huangapple
  • 本文由 发表于 2023年2月8日 22:29:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75387249.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定