Shell脚本的动态补丁计数器
我正在Solaris 10 SPARC机器上开发一个脚本,用于计算在补丁交付期间成功安装了多少补丁。我想向用户显示: (十) 已成功安装33个修补程序中的一个 我希望我的脚本输出动态替换“X”,以便用户知道有活动发生;有点像柜台。我能显示计数,但只能在新的一行上显示。如何使括号在脚本执行检查时动态更新?不要担心“通过/失败”。。。我主要关心的是更新括号中的输出Shell脚本的动态补丁计数器,shell,for-loop,solaris,counter,wc,Shell,For Loop,Solaris,Counter,Wc,我正在Solaris 10 SPARC机器上开发一个脚本,用于计算在补丁交付期间成功安装了多少补丁。我想向用户显示: (十) 已成功安装33个修补程序中的一个 我希望我的脚本输出动态替换“X”,以便用户知道有活动发生;有点像柜台。我能显示计数,但只能在新的一行上显示。如何使括号在脚本执行检查时动态更新?不要担心“通过/失败”。。。我主要关心的是更新括号中的输出 for x in `cat ${PATCHLIST}` do if ( showrev -p $x | grep $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
通常的方法是在某个点发出一个
\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;它使用grep
的-s
选项保持安静
我仍然对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中的文件,并统计输出的行数。这意味着您可以在awk
脚本中简单地打印$0
,因为$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 "" }'
当然,这要追溯到读取每个文件,但您现在可以从中获得更精确的信息(这是对更精确信息的惩罚)。以下是我如何让修补程序安装脚本按我想要的方式工作的:
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
读取pkgline时
做
patchadd-d${pkgline}>/var/log/patch_install.log 2>&1
#为进度指示器创建审核文件
对于${pkgline}中的x
做
if(showrev-p${x}grep-i${x}>/dev/null 2>&1);然后
echo“${x}”>>/tmp/pass
其他的
echo“${x}”>>/tmp/fail
fi
完成
#进度指标
对于'wc-l/tmp/pass | awk'{print$1}'中的y`
做
printf“\r${y}在为`hostname`安装的`wc-l/patchdir/master | awk'{print$1}`程序包中。上次安装的修补程序:(${pkgline})”
完成
完成
谢谢你,乔纳森,这非常有帮助!感谢优秀的反馈。