1

我正在 Solaris 10 SPARC 机器上开发一个脚本来计算在补丁交付期间成功安装了多少补丁。我想向用户显示:

(X) 33个补丁安装成功

我希望我的脚本能够动态输出替换“X”,以便用户知道正在发生活动;有点像柜台。我能够显示计数,但只能在新行上。当脚本执行检查时,如何使括号动态更新?不要担心“通过/失败”......我主要关心的是在括号中更新我的输出。

for x in `cat ${PATCHLIST}`
do
    if ( showrev -p $x | grep $x > /dev/null 2>&1 ); then
        touch /tmp/patchcheck/* | echo "pass" >> /tmp/patchcheck/$x
        wc /tmp/patchcheck/* | tail -1 | awk '{print $1}'
    else
        touch /tmp/patchcheck/* | echo "fail" >> /tmp/patchcheck/$x
        wc /tmp/patchcheck/* | tail -1 | awk '{print $1}'
    fi
done
4

2 回答 2

2

执行此操作的常用方法是在某个点发出\r回车 (CR) 并\n在行尾省略换行符或换行符 (LF)。由于您使用的是awk,您可以尝试:

awk '{printf "\r%s", $1} END {print ""}'

对于大多数行,它输出回车和字段 1 中的数据(末尾没有换行符)。在输入结束时,它会打印一个空字符串,后跟一个换行符。

另一种可能性是您应该将awk脚本放在for循环之外:

for x in `cat ${PATCHLIST}`
do
    if ( showrev -p $x | grep $x > /dev/null 2>&1 ); then
        touch /tmp/patchcheck/* | echo "pass" >> /tmp/patchcheck/$x
        wc /tmp/patchcheck/* | tail -1
    else
        touch /tmp/patchcheck/* | echo "fail" >> /tmp/patchcheck/$x
        wc /tmp/patchcheck/* | tail -1
    fi
done | awk '{ printf "\r%s", $1} END { print "" }'

我不确定,但我认为您可以对脚本中的其余重复代码应用类似的简化:

for x in `cat ${PATCHLIST}`
do
    if showrev -p $x | grep -s $x
    then echo "pass"
    else echo "fail"
    fi >> /tmp/patchcheck/$x
    wc /tmp/patchcheck/* | tail -1
done | awk '{ printf "\r%s", $1} END { print "" }'

这消除了touch(这似乎没有多大作用),尤其是当空输出touch被管道传输到echo忽略其标准输入时。它消除了行中的子shell if;它使用-s选项grep来保持安静。

我还是有点怀疑这wc条线。我认为您实际上是在计算文件的数量,因为每个文件都应该包含一行(通过或失败),除非您在由${PATCHLIST}. 在这种情况下,我可能会使用:

for x in `cat ${PATCHLIST}`
do
    if showrev -p $x | grep -s $x
    then echo "pass"
    else echo "fail"
    fi >> /tmp/patchcheck/$x
    ls /tmp/patchcheck | wc -l
done | awk '{ printf "\r%s", $1} END { print "" }'

这会列出 /tmp/patchcheck 中的文件并计算输出的行数。$0这意味着您可以简单地在awk脚本中打印,因为$0$1是相同的。在某种程度上效率很重要(不是很多),这更有效,因为ls只扫描一个目录,而不是wc打开每个文件。但它更准确地描述了您正在尝试做的事情。如果您以后想计算通行证,可以使用:

for x in `cat ${PATCHLIST}`
do
    if showrev -p $x | grep -s $x
    then echo "pass"
    else echo "fail"
    fi >> /tmp/patchcheck/$x
    grep '^pass$' /tmp/patchcheck/* | wc -l
done | awk '{ printf "\r%s", $1} END { print "" }'

当然,这可以追溯到读取每个文件,但是您现在可以从中获得更精炼的信息(这是对更精炼信息的惩罚)。

于 2012-03-19T23:34:10.513 回答
1

以下是我如何让我的补丁安装脚本按照我想要的方式工作:

while read pkgline
do
    patchadd -d ${pkgline} >> /var/log/patch_install.log 2>&1
    # Create audit file for progress indicator
    for x in ${pkgline}
    do
        if ( showrev -p ${x} | grep -i ${x} > /dev/null 2>&1 ); then
            echo "${x}" >> /tmp/pass
        else
            echo "${x}" >> /tmp/fail
        fi
    done
    # Progress indicator
    for y in `wc -l /tmp/pass | awk '{print $1}'`
    do
        printf "\r${y} out of `wc -l /patchdir/master | awk '{print $1}'` packages installed for `hostname`.  Last patch installed: (${pkgline})"
    done
done < /patchdir/master
于 2012-04-25T21:48:25.477 回答