linux - bash - 尝试通过管道将命令运行到单独的函数时出错

标签 linux bash parallel-processing job-scheduling variable-expansion

我正在尝试获取此功能,以便轻松并行化我的 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
> 

最佳答案

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

关于linux - bash - 尝试通过管道将命令运行到单独的函数时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10509558/

相关文章:

java - 将输出重定向到滚动文件

linux - shell脚本中的奇怪输出

bash - bash 中 while 循环中的实数

c# - 为什么在C#中首次调用的并行处理要慢得多?

c++ - 非for循环的OpenMP并行化

c - 如何在 "mongoose webserver"(Linux) 上处理/杀死 cgi 脚本 (C++) 的 Zombie 或 <defunct> 进程?

Linux 上的 java.lang.UnsatisfiedLinkError

linux - Shebang 导致脚本失败

linux - 使用 awk(或熟悉的)将多行合并为 1 行

c++ - 如何降低程序的 CPU 使用率?