What's the most elegant way to add Redis to /etc/services? What's the most elegant way to add Redis to /etc/services? shell shell

What's the most elegant way to add Redis to /etc/services?


A single line sort that puts it in the right place:

echo -e "redis\t\t6379/tcp" | sort -k2 -n -o /etc/services -m - /etc/services


Nothing in the rules against answering my own question - this one uses Redis exclusively:

cat /etc/services | redis-cli -x SET services; redis-cli --raw EVAL 'local s = redis.call("GET", KEYS[1]) local b, p, name, port, proto; p = 1 repeat b, p, name, port, proto = string.find(s, "([%a%w\-]*)%s*(%d+)/(%w+)", p) if (p and tonumber(port) > tonumber(ARGV[2])) then s = string.sub(s, 1, b-1) .. ARGV[1] .. "\t\t" .. ARGV[2] .. "/" .. ARGV[3] .. "\t\t\t# " .. ARGV[4] .. "\n" .. string.sub(s, b, string.len(s)) return s end until not(p)' 1 services redis 6379 tcp "remote dictionary server" > /etc/services

Formatted Lua code:

local s = redis.call("GET", KEYS[1])local b, p, name, port, protop = 1repeat    b, p, name, port, proto = string.find(s, "([%a%w\-]*)%s*(%d+)/(%w+)", p)    if (p and tonumber(port) > tonumber(ARGV[2])) then        s = string.sub(s, 1, b-1) .. ARGV[1] .. "\t\t" .. ARGV[2]         .. "/" .. ARGV[3] .. "\t\t\t# " .. ARGV[4] .. "\n"         .. string.sub(s, b, string.len(s))        return s    end until not(p)

Note: a similar challenge (https://gist.github.com/jorinvo/2e43ffa981a97bc17259#gistcomment-1440996) had inspired this answer. I chose a pure Lua script approach instead of leveraging Sorted Sets... although I could :)


An idempotent awk one-liner that inserts 6379 in order would be:

awk -v inserted=0 '/^[a-z]/ { if ($2 + 0 == 6379) { inserted=1 }; if (inserted == 0 && $2 + 0 > 6379) { print "redis\t\t6379/tcp"; inserted=1 }; print $0 }' /etc/services > /tmp/services && mv /tmp/services /etc/services