4

我目前正在修改一个大型 BASH 脚本,该脚本在几个不同的发行版(主要是基于 Redhat 和 Debian)中安装/检查一系列包。

为了处理发行版之间的一些差异(例如 rpm 与 dpkg、yum 与 apt 等),我尝试使用各种命令字符串加载一些变量,以使脚本中不包含if debian then this, otherwise this语句。但是,它似乎awk不喜欢放在 eval 语句中,我不知道为什么。

例子

# Example dpkg --list output
# ii  bash       4.1-2ubuntu3    The GNU Bourne Again SHell

dpkg --list | grep 'bash'
# Outputs bash entries in dpkg.

cmd="dpkg --list | grep 'bash'"
eval $cmd                                       
# Outputs as expected, same as above.

dpkg --list | awk '/^.i/ { print $2 }'
# Outputs as expected, a list of package names.

cmd="dpkg --list | awk '/^.i/ { print $2 }'"
eval $cmd
# Awk prints full output from dpkg for every line matching the regex.

在上面的代码中,简单地对给定的包进行 grepping 可以正常工作,并且可以按预期打印,但是当尝试使用 awk 生成包名的完整列表时,print $2似乎会被忽略并简单地打印整行。

有任何想法吗?

4

3 回答 3

7

这是原因:

cmd="dpkg --list | awk '/^.i/ { print $2 }'"
echo $cmd

Output:
dpkg --list | awk '/^.i/ { print }'

转义 $ 符号:

cmd="dpkg --list | awk '/^.i/ { print \$2 }'"
于 2012-07-12T09:58:38.403 回答
0

eval 可以评估 $2 并用它的值替换它试试这个(转义 $ char)。

cmd="dpkg --list | awk '/^.i/ { print \$2 }'"
于 2012-07-12T09:57:56.667 回答
0

你想要这个(必须在 awk 脚本中转义 $):

cmd="dpkg --list | awk '/^.i.+bash/{ print \$2 }'"
eval $cmd

我仍然不明白你为什么eval在这种情况下使用它,它会导致几个问题,(其中一个是你显然不能使用/^.i.*bash/正则表达式(shell 扩展 glob 或\在正则表达式内部传递)并且必须解析为/^.i.+bash/.

于 2012-07-12T10:09:19.133 回答