我目前正在修改一个大型BASH脚本,该脚本在几个不同的发行版(主要是基于Redhat和Debian)中安装/检查一系列软件包。
要处理发行版之间的一些差异(例如rpm vs dpkg,yum vs 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
似乎被忽略并且只是打印出来全线。
有什么想法吗?
答案 0 :(得分:5)
这就是原因:
cmd="dpkg --list | awk '/^.i/ { print $2 }'"
echo $cmd
Output:
dpkg --list | awk '/^.i/ { print }'
逃离$符号:
cmd="dpkg --list | awk '/^.i/ { print \$2 }'"
答案 1 :(得分:0)
eval可以评估$ 2并用它的值替换它试试这个(转义$ char)。
cmd="dpkg --list | awk '/^.i/ { print \$2 }'"
答案 2 :(得分:0)
你想要这个(要在awk脚本中转义$):
cmd="dpkg --list | awk '/^.i.+bash/{ print \$2 }'"
eval $cmd
我仍然不明白你为什么在这种情况下使用eval
,这会导致一些问题,
(其中一个是你显然不能使用/^.i.*bash/
正则表达式(shell扩展glob或在正则表达式中传递\
)并且必须解析为/^.i.+bash/
。