Shell脚本的动态补丁计数器

时间:2012-03-19 22:44:59

标签: shell for-loop solaris counter wc

我正在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

2 个答案:

答案 0 :(得分: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时。它消除了if行中的子shell;它使用-s的{​​{1}}选项来保持安静。

我仍然对grep行有点怀疑。我认为您实际上需要计算文件数,因为每个文件应包含一行(通过或失败),除非您在wc标识的文件中列出了两次补丁。在这种情况下,我可能会使用:

${PATCHLIST}

列出/ tmp / patchcheck中的文件并计算输出的行数。这意味着您只需在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 "" }' 脚本中打印$0,因为awk$0是相同的。在效率很重要的情况下(不是很多),这更有效,因为$1仅扫描目录,而不是让ls打开每个文件。但它更具体地说明了您要做的事情。如果您以后想要计算通行证,可以使用:

wc

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

答案 1 :(得分: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