英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论