Skip to main content
Topic: My bash-completion for dinit (Read 535 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

My bash-completion for dinit

Hi, I'm just your average dinit enjoyer.
I wanted to save those couple extra seconds on starts/restarts/stops because I do them quiet often so I made this for myself and decided to share here in case someone wants to make use of it.

The only requirement is having the list command (as root)
Code: [Select]
# dinitctl list
set as password-less so we can retrieve the currently running services for root.
This is easily accomplished on doas by editing the `/etc/doas.conf` and adding the following (or equivalent)
Code: [Select]
permit nopass :wheel as root cmd dinitctl args list

Then the following goes into `~/.local/share/bash-completion/completions/dinitctl`.
Code: [Select]
#!/bin/sh
_dinitctl_prefix=doas
_dinitctl_ignore_services="boot|binfmt|cgroups|cleanup|dbus|dbus-pre|dmesg|fsck|getty|hostname|hwclock|kmod-static-nodes|locale|logind|loginready|misc|modules|mount|mount-all|network|net-lo|pseudofs|random-seed|rclocal|recovery|root-rw|seatd|setup|single|swap|sysctl|sysusers|tmpfiles-dev|tmpfiles-setup|tmpfs|tty1|tty2|tty3|tty4|tty5|tty6|udev-settle|udev-trigger|udevd|vconsole"
_dinitctl_system_path="/etc/dinit.d/"
_dinitctl_user_path="$HOME/.config/dinit.d/"

_dinit_services() {
local cur=${COMP_WORDS[COMP_CWORD]}
local thr=1
local flags=()
for word in "${COMP_WORDS[@]}"; do
if [[ $word == -* || $word == --* ]]; then
flags+=($word)
fi
done
((thr+=${#flags[@]}))

if [ ${COMP_CWORD} -gt $(($thr + 1)) ]; then
return
fi

if [[ " ${flags[*]} " == *" -s "* || " ${flags[*]} " == *" --system "* ]]; then
_dinitctl_path=$_dinitctl_system_path
__dinitctl_prefix=$_dinitctl_prefix
elif [[ " ${flags[*]} " == *" -u "* || " ${flags[*]} " == *" --user "* ]]; then
_dinitctl_path=$_dinitctl_user_path
__dinitctl_prefix=""
else
_dinitctl_path=$_dinitctl_system_path
__dinitctl_prefix=$_dinitctl_prefix
fi


if [ ${COMP_CWORD} -eq $thr ]; then
COMPREPLY=($(compgen -W "status list start stop restart enable disable" -- "$cur"))
return
fi

local services
case "${COMP_WORDS[$thr]}" in
"start")
services=$(_dinit_stopped_services)
;;
"stop")
services=$(_dinit_running_services)
;;
"restart")
services=$(_dinit_running_services)
;;
"status")
services=$(_dinit_all_services)
;;
"disable")
services=$(_dinit_enabled_services)
;;
"enable")
services=$(_dinit_disabled_services)
;;
esac
if [ -z "$services" ]; then
return
fi
COMPREPLY=($(compgen -W "$services" -- "$cur"))
}

_dinit_all_services() {
/usr/bin/ls -p $_dinitctl_path | grep -v / | grep -v -E "$_dinitctl_ignore_services"
}

_dinit_enabled_services() {
/usr/bin/ls -p $_dinitctl_path/boot.d/ | grep -v / | grep -v -E "$_dinitctl_ignore_services"
}

_dinit_running_services() {
$__dinitctl_prefix dinitctl list | grep -E "\{\+\}|\[\+\]" | awk '{print $3}' | grep -v -E "$_dinitctl_ignore_services"
}

_dinit_stopped_services() {
_dinit_all_services | grep -v -x -f <(_dinit_running_services)
}

_dinit_disabled_services() {
_dinit_all_services | grep -v -x -f <(_dinit_enabled_services)
}

complete -F _dinit_services dinitctl

Yes those aren't all the arguments, I know, but I personally prefer not to overflow my tab completions with stuff I'm only gonna use once or twice, feel free to add them on yours tho. Same goes for the reason behind the ignored services list.

You can just change the `stop|restart` case function to something like `_dinit_all_services` or modify the function itself if you don't wanna do the password-less thing as I don't think there's a way around it (?)

I hope one day dinitcheck gets renamed to dinit-check so I can save 2 characters worth of time before pressing tab when typing dinitctl.

Re: My bash-completion for dinit

Reply #1
I have in ~/.bashrc:
Code: [Select]
alias dctl='dinitctl'