Pregunta

I'm currently in the process of modifying a large BASH script which installs/checks a series of packages in a few different distros (mainly Redhat and Debian based).

To handle some of the differences between the distros (e.g. rpm vs dpkg, yum vs apt, etc) I'm trying to load some variables with various command strings so that the script isn't full of if debian then this, otherwise this statements. However it appears that awk doesn't like being put inside an eval statement, and I can't figure out why.

Example

# 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.

In the code above, simply grepping for a given package works fine, and prints as expected, but when trying to generate a full list of package names using awk, the print $2 appears to be ignored and simply prints the full line.

Any ideas?

¿Fue útil?

Solución

This is the reason:

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

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

Escape the $ sign:

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

Otros consejos

eval may evaluate $2 and replace it by its values try this (escape the $ char).

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

You want this (gotta escape $ in awk script):

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

Still I do not understand why you use eval in this case, it causes several problems here, (one of which is that you apparently cannot use /^.i.*bash/ regex (shell expands glob or passes \ inside regex) and have to resolve to /^.i.+bash/.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top