【问题标题】:Bash script - For loop multiple arguments and awkBash 脚本 - For 循环多个参数和 awk
【发布时间】:2012-03-22 20:53:41
【问题描述】:

我正在尝试编写一个 BASH 脚本来修补我的 CentOS 服务器。我的目标是,当我运行脚本时,它会输出包名、当前安装的版本和新的包版本。像这样的:

nspr.x86_64 / 4.8.8-3.el6 / 4.8.9-3.el6_2

这样,如果我因为某个包损坏了某些东西而需要降级,我会记录下来。

yum check-update 命令给了我上面列出的第一条信息(包名)和第三条信息(新版本),我可以使用awk 将两者分开。之后很容易;只需运行rpm -q {package} 即可获取第二条信息,然后将它们连接起来。

但是,我在代码中遇到了for 循环的问题。我需要将多个参数传递到循环中(包名称和较新版本),以便稍后echo 它们。

这是我的代码:

for package in `/usr/bin/yum --cacheonly --noplugins check-update | awk '{print $1, $2}'`;
do
    OLD_VER=`rpm -q ${package}` # ${package} should actually be $1 from the awk statement above

    NEW_VER=${2} # This is $2 from the awk statement above

    echo "${package} / ${OLD_VER} / ${NEW_VER}"
done

请原谅代码中的明显错误;我是 BASH 脚本的新手。我的困惑主要源于 awk;我不太熟悉它,也不熟悉它如何与 BASH 脚本交互。但是,我认为很清楚我要做什么。 package 是否作为数组传递?有没有更好的方法来做到这一点?

【问题讨论】:

  • 一种解决方案是在 awk 中完成所有工作

标签: bash for-loop awk centos yum


【解决方案1】:

你想阅读整行:

 /usr/bin/yum --cacheonly --noplugins check-update |
 while read line; do
   set - $line;
   echo first: $1 second: $2
 done

【讨论】:

  • 你应该让read做分裂; yum ... | while read first second; do ...
【解决方案2】:

试试这个:

/usr/bin/yum --cacheonly --noplugins check-update \
    | awk '{package=$1; newVer=$2; cmd = "rpm -q " package; cmd | getline oldVer; close(cmd); print package " / " oldVer " / " newVer}'

您的脚本的问题在于,尽管 bash 和 awk 都使用 $ 来引用变量,但它们是不同的变量,您不能从 bash 引用 awk 的 $2,反之亦然。用 awk 或 bash 编写所有内容应该可以解决问题。

【讨论】:

  • 有没有办法使用我当前的脚本使用 set 来做到这一点?我刚刚找到了这个例子:tldp.org/LDP/abs/html/loops1.html 如果你看的话,示例 11-2 使用 set 命令来分隔字符串输入。
  • 是的,set $(yum ... | awk ...) 很简单。但是while read 可能更优雅、更易读。
猜你喜欢
  • 2015-06-16
  • 2020-01-31
  • 1970-01-01
  • 1970-01-01
  • 2016-10-30
  • 2013-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多