I have to edit a config automatically before starting a service in a docker container (a storm supervisor), and I want to append something like this in /opt/storm/conf/storm.yaml: storm.local.hostname: (extracted from /etc/hosts)

What I currently do is that:

echo -n "storm.local.hostname: " >> /opt/storm/conf/storm.yaml && head -1 /etc/hosts | awk -F ' ' {'print $1'} | xargs echo >> /opt/storm/conf/storm.yaml

How can I improve on that, on a readability POV? It looks pretty obfuscated to me, but I may just be naive ^^

Disclaimer: this runs inside a docker container, so there's only access to classic bash.

  • \$\begingroup\$ What is special about the line of /etc/hosts that makes it the correct entry to fetch? Why aren't you looking up a hostname instead? \$\endgroup\$ – 200_success Jun 15 '15 at 21:04
  • \$\begingroup\$ @200_success : In my docker container, "hostname" returns the container tag (so something like adef456fd), and I'm interested in the ip of the container (so something like, and I found out there's the resolution in /etc/hosts If there's a better solution, I totally can hear it :) \$\endgroup\$ – C4stor Jun 16 '15 at 7:25

How can I improve on that, on a readability POV? It looks pretty obfuscated to me, but I may just be naive ^^

You're not naive, it looks obfuscated ;-)

A couple of general tips first:

  • When you find yourself writing the same path twice, put it in a variable

    • to avoid duplicated hard coded strings
    • to make it easy to change the path later if needed
    • to give it a meaningful descriptive name
  • Avoid echo -n. In general, avoid all echo statements that use any flags like -n, -e, because these are not portable. When you need those extra functions, printf is more portable. Plain echo with no flags, just stuff to print is nice, short and sweet

  • When you see head and awk in the same pipeline, usually you can rewrite with just awk. It saves the execution of one process.

  • I think head -NUM is deprecated. To be safe, I suggest to use head -n NUM instead.

  • To avoid extremely long lines, break the line with a \

A couple of specific tips in the context of your example:

  • The one-liner first appends some fixed text to the config file, and then appends some more text by way of awk. Since awk can print fixed text too, the echo is not needed at all.

  • xargs seems pointless: you could just redirect the output of awk

  • The separator ' ' you used with awk seems both unnecessary and error prone. The hosts file might have entries separated by tab. Simply by not specifying a separator, awk will work with both cases, space or tab separated.

Following the suggestions above, the one-liner could be simplified to:

awk '{print "storm.local.hostname: " $1; exit}' < /etc/hosts >> /opt/storm/conf/storm.yaml
| improve this answer | |
  • \$\begingroup\$ This looks good, and works flawlessly. Thanks :) \$\endgroup\$ – C4stor Jun 16 '15 at 8:45
  • \$\begingroup\$ The ` < ` is not required I believe? \$\endgroup\$ – h.j.k. Jun 17 '15 at 6:53
  • \$\begingroup\$ On my system, it doesn't appear to do a difference indeed :) \$\endgroup\$ – C4stor Jun 17 '15 at 6:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.