如何向 bash 脚本添加线程?
How to add threading to the bash script?
#!/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 个输入并且需要很多时间?
您可以通过&
将任务发送到后台。如果您打算等待所有这些完成,您可以使用 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
不过请注意:后台进程可能会弄乱输出,因为它们会 运行 异步。您可能希望使用 命名管道 来收集它们的输出。
简单的方法。假设输出的顺序不重要,and snmpwalk
的输出没有意义 if 它应该失败,放一个&&
在每个背景命令的末尾,除了最后一个命令应该在末尾有一个 &
:
#!/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
不太简单。如果 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
大括号可以包含更复杂的 if ... then ... else ... fi
语句,所有这些语句都将作为背景。
对于那些没有要测试的复杂 snmpwalk
命令的人来说,这里有一个类似的循环,它打印 1 到 5,但在 echo
命令之间随机休眠:
for f in {1..5}; do
RANDOM=$f &&
sleep $((RANDOM/6000)) &&
echo $f &
done 2> /dev/null | cat
每次输出都相同(删除 RANDOM=$f &&
以获得不同的输出),并且需要三秒才能 运行:
2
4
1
3
5
将其与不带 &&
和 &
的代码 进行比较:
for f in {1..5}; do
RANDOM=$f
sleep $((RANDOM/6000))
echo $f
done 2> /dev/null | cat
当 运行 时,代码需要 7 秒到 运行,输出为:
1
2
3
4
5
#!/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 个输入并且需要很多时间?
您可以通过&
将任务发送到后台。如果您打算等待所有这些完成,您可以使用 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
不过请注意:后台进程可能会弄乱输出,因为它们会 运行 异步。您可能希望使用 命名管道 来收集它们的输出。
简单的方法。假设输出的顺序不重要,and
snmpwalk
的输出没有意义 if 它应该失败,放一个&&
在每个背景命令的末尾,除了最后一个命令应该在末尾有一个&
:#!/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
不太简单。如果
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
大括号可以包含更复杂的
if ... then ... else ... fi
语句,所有这些语句都将作为背景。
对于那些没有要测试的复杂 snmpwalk
命令的人来说,这里有一个类似的循环,它打印 1 到 5,但在 echo
命令之间随机休眠:
for f in {1..5}; do
RANDOM=$f &&
sleep $((RANDOM/6000)) &&
echo $f &
done 2> /dev/null | cat
每次输出都相同(删除 RANDOM=$f &&
以获得不同的输出),并且需要三秒才能 运行:
2
4
1
3
5
将其与不带 &&
和 &
的代码 进行比较:
for f in {1..5}; do
RANDOM=$f
sleep $((RANDOM/6000))
echo $f
done 2> /dev/null | cat
当 运行 时,代码需要 7 秒到 运行,输出为:
1
2
3
4
5