[arch-projects] [initscripts] simple rc.d bash completion script

Dave Reisner d at falconindy.com
Wed May 18 13:13:02 EDT 2011


On Thu, May 19, 2011 at 12:53:13AM +0800, Auguste Pop wrote:
> i have made a small patch to initscripts to allow for a simple bash
> completion function.
> 
> i am not familiar with git, i made the patch by git clone, git branch,
> git commit, and git show.
> 
> the patch is at http://paste.pocoo.org/show/391299/ and also
> copy-pasted as follows:
> 
> commit a430fcfb8fcd1e268609473c9a722e1cae1a66f0
> Author: Auguste Pop <auguste at gmail.com>
> Date:   Thu May 19 00:36:44 2011 +0800
> 
>    add a simple bash completion file
> 
> diff --git a/Makefile b/Makefile
> index 6923840..15df4cf 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1,5 +1,5 @@
>  VER  := $(shell git describe)
> -DIRS := /etc/rc.d /etc/conf.d /etc/rc.d/functions.d /etc/cron.hourly /sbin
> +DIRS := /etc/rc.d /etc/conf.d /etc/rc.d/functions.d /etc/cron.hourly
> /sbin /etc/bash_completion.d
> 
>  minilogd: minilogd.o
> 
> @@ -13,6 +13,7 @@ install: minilogd installdirs
>        install -m755 -t $(DESTDIR)/etc/cron.hourly adjtime
>        install -m755 -t $(DESTDIR)/etc/rc.d functions hwclock network netfs
>        install -m755 -t $(DESTDIR)/sbin minilogd rc.d
> +       install -m644 bash_completion $(DESTDIR)/etc/bash_completion.d/rc.d
> 
>  clean:
>        rm -f minilogd minilogd.o
> diff --git a/bash_completion b/bash_completion
> new file mode 100644
> index 0000000..a3bd8ed
> --- /dev/null
> +++ b/bash_completion
> @@ -0,0 +1,55 @@
> +#!/bin/bash
> +
> +_rc.d_getdaemons ()
> +{
> +    /usr/bin/find "$1" -mindepth 1 -maxdepth 1 -type f -printf '%f\n'
> +}

It would be nice to avoid the fork here. This can easily be accomplished
as:

  local -a files=("$1"/*)
  printf '%s\n' "${files[@]##*/}"

Also, please avoid using '.' in bash functions names. While bash will
allow you to set this, it's technically wrong, and unset will not allow
you to remove the function from your environment.

> +_rc.d_arraydiff ()
> +{
> +    local arr
> +    declare -A arr
> +
> +    for elem in "${!1}"
> +    do
> +        arr[$elem]=1
> +    done
> +    for elem in "${!2}"
> +    do
> +        unset arr[$elem]
> +    done
> +    echo "${!arr[@]}"
> +}

We use 'for i in group; do' and 'if commands; then' everywhere else
in our code.

> +
> +_rc.d ()
> +{
> +    local command commands available started
> +    local cur words cword
> +
> +    commands="list help start stop restart"
> +    available=($(_rc.d_getdaemons /etc/rc.d))
> +    started=($(_rc.d_getdaemons /run/daemons))
> +
> +    _get_comp_words_by_ref -n =: cur words cword
> +    [ $cword -gt 1 ] && command=${words[1]}
> +
> +    if [ -z "$command" ]

This is Bash, not posix. Please use [[.

> +    then
> +        COMPREPLY=($(compgen -W "$commands" -- $cur))
> +    else
> +        case "$command" in
> +            start)
> +                COMPREPLY=($(compgen -W "$(_rc.d_arraydiff \
> +                    available[@] started[@])" -- $cur))
> +                ;;
> +            stop|restart)
> +                COMPREPLY=($(compgen -W "$(echo ${started[@]})" -- $cur))
> +                ;;
> +            list|help|*)
> +                COMPREPLY=()
> +                ;;
> +        esac
> +    fi
> +}
> +
> +complete -F _rc.d rc.d


More information about the arch-projects mailing list