我正在尝试使用此功能,以便轻松地并行化我的bash脚本。这个想法很简单;而不是按顺序运行每个命令,我将我要运行的命令传递给此函数,并且它在读取行时执行;为我运行bg中的工作并负责物流....但它不起作用。我添加了set -x,其中的东西被执行了,看起来我在想要执行的东西周围得到奇怪的引用......我该怎么办?
runParallel () {
while read line
do
while [ "`jobs | wc -l`" -eq 8 ]
do
sleep 2
done
{
set -x
${line}
set +x
} &
done
while [ "`jobs | wc -l`" -gt 0 ]
do
sleep 1
jobs >/dev/null 2>/dev/null
echo sleeping
done
}
for H in `ypcat hosts | grep fmez | grep -v mgmt | cut -d\ -f2 | sort -u`
do
echo 'ping -q -c3 $H 2>/dev/null 1>/dev/null && echo $H - UP || echo $H - DOWN'
done | runParallel
当我运行它时,我得到如下输出:
> ./myscript.sh
+ ping -q -c3 '$H' '2>/dev/null' '1>/dev/null' '&&' echo '$H' - UP '||' echo '$H' - DOWN
Usage: ping [-LRUbdfnqrvVaA] [-c count] [-i interval] [-w deadline]
[-p pattern] [-s packetsize] [-t ttl] [-I interface or address]
[-M mtu discovery hint] [-S sndbuf]
[ -T timestamp option ] [ -Q tos ] [hop1 ...] destination
+ set +x
sleeping
>
答案 0 :(得分:1)
如果我正确理解了这一点,您可能不希望在echo命令中使用单引号。单引号是文字字符串,不解释您的bash变量$ H。
答案 1 :(得分:1)
set -x
输出中的引号不是问题,至多它们是问题的另一个结果。主要问题是${line}
与eval ${line}
不同。
扩展变量时,结果单词不会被视为shell保留结构。这是预期的,这意味着例如。
A="some text containing > ; && and other weird stuff"
echo $A
不会对无效语法大喊大叫,但会打印变量值。
但是在你的函数中,它意味着${line}
中的所有单词,包括2>/dev/null
等,都作为参数传递给ping,set -x
输出很好地显示,所以ping抱怨。
如果要使用带有重定向和条件的变量复杂命令行执行,则必须使用eval
。
答案 2 :(得分:1)
与GNU Parallel的许多用户一样,您似乎编写了自己的并行程序。
如果你安装了GNU Parallel http://www.gnu.org/software/parallel/,你可以这样做:
cat hosts | parallel -j8 'ping -q -c3 {} 2>/dev/null 1>/dev/null && echo {} - UP || echo {} - DOWN'
您可以通过以下方式安装GNU Parallel:
wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem
观看GNU Parallel的介绍视频了解详情: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
答案 3 :(得分:0)