upstart support for service completion

initctl list works for unprivileged users.

Wasn't sure what file to check to detect that upstart was present, but
/sbin should always be mounted, and upstart itself provides
/sbin/upstart-udev-bridge, and it's not a conffile in /etc that someone
could move if they wanted to on their local system.  upstart-dbus-bridge
isn't present on Ubuntu 12.04, but socket and udev bridge both are.
(Do Debian kFreeBSD or GNU/Hurd have udev?  nvm, Debian kFreeBSD doesn't
ship upstart at all.)

http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/lucid/upstart/lucid-updates/view/head:/debian/changelog
indicates that the udev bridge existed as far back as Ubuntu 10.04
(Lucid), and might have been the first bridge.  udev is probably here to stay, so use that, even udev is Linux only, unlike sockets.

 Another possiblity would be to check /usr/share/man/man7/upstart.7.gz,
but that looks brittle.

 I think it's important to check that the system is using an upstart init,
so you don't run initctl when completing in a root shell on another kind
of system.  At worst, reboots, at best generates system log messages.
This commit is contained in:
Peter Cordes 2014-12-13 00:34:57 -04:00 committed by Ville Skyttä
parent 976ad96007
commit 3567d9354f

View File

@ -1137,6 +1137,10 @@ _services()
COMPREPLY+=( $( systemctl list-units --full --all 2>/dev/null | \ COMPREPLY+=( $( systemctl list-units --full --all 2>/dev/null | \
awk '$1 ~ /\.service$/ { sub("\\.service$", "", $1); print $1 }' ) ) awk '$1 ~ /\.service$/ { sub("\\.service$", "", $1); print $1 }' ) )
if [[ -x /sbin/upstart-udev-bridge ]]; then
COMPREPLY+=( $( initctl list 2>/dev/null | cut -d' ' -f1 ) )
fi
COMPREPLY=( $( compgen -W '${COMPREPLY[@]#${sysvdirs[0]}/}' -- "$cur" ) ) COMPREPLY=( $( compgen -W '${COMPREPLY[@]#${sysvdirs[0]}/}' -- "$cur" ) )
} }