Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 75225 - /etc/init.d-scripts bash_completion breaks timidity
Summary: /etc/init.d-scripts bash_completion breaks timidity
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: All All
: High normal (vote)
Assignee: Gentoo Shell Tools project
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-12-21 12:01 UTC by Ed Catmur
Modified: 2005-01-12 03:35 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Catmur 2004-12-21 12:01:56 UTC
$ timidity <tab><tab>
broken   iuse     pause    start    usesme
ineed    needsme  restart  stop     zap

Expected: directories, and .midi files.

This is because timidity installs /etc/init.d/timidity which gets picked up by the /etc/init.d/* completion:

complete -W "start stop restart pause zap ineed needsme iuse usesme broken" \
	$(for i in /etc/init.d/*; do echo ${i##*/}; done)

I don't see why this can't just be

complete -W "start stop restart pause zap ineed needsme iuse usesme broken" \
	/etc/init.d/*

after all you can't control an initscript just with its name, and completing with full path works for bash.
Comment 1 Ed Catmur 2004-12-21 12:33:36 UTC
Oh, and the extra opts= stuff needs handling as well - I think something like

#
# completion for Gentoo style init
#
_gentoo_style_init()
{
	local script="${COMP_WORDS[0]}"
	[[ -r "$script" ]] || return 1
	COMPREPLY=($(opts="start stop restart pause zap ineed needsme iuse usesme broken"; source "$script"; echo "$opts"))
	[[ "$COMPREPLY" ]] || COMPREPLY=(start stop restart zap)
	return 0
}
complete -F _gentoo_style_init /etc/init.d/*

should work.
Comment 2 Ed Catmur 2004-12-21 12:51:42 UTC
Oops. That should be:

#
# completion for Gentoo style init
#
_gentoo_style_init()
{
	local script="${COMP_WORDS[0]}"
	[[ "$COMP_CWORD" -gt 1 ]] && return 1
	[[ -r "$script" ]] || return 1
	COMPREPLY=($(opts="start stop restart pause zap ineed needsme iuse usesme broken"; source "$script"; echo "$opts"))
	[[ "$COMPREPLY" ]] || COMPREPLY=(start stop restart zap)
	COMPREPLY=($(compgen -W "${COMPREPLY[*]}" ${COMP_WORDS[COMP_CWORD]}))
	return 0
}
complete -F _gentoo_style_init /etc/init.d/*

Comment 3 Ed Catmur 2004-12-21 13:05:33 UTC
Gah! That's wrong as well - luckily I wasn't running as root when I typed /etc/init.d/shutdown.sh <tab>...

Perhaps sourcing /etc/init.d-scripts is a bad idea? I think it's probably OK if they're proper runscript-scripts:

#
# completion for Gentoo style init
#
_gentoo_style_init()
{
	local script="${COMP_WORDS[0]}"
	local cur="${COMP_WORDS[$COMP_CWORD]}"
	[[ -r "$script" ]] || return 1
	if [[ "$(head -n 1 "$script")" = "#!/sbin/runscript"* ]]; then
		[[ "$COMP_CWORD" -gt 1 ]] && return 1
		COMPREPLY=($(opts="start stop restart pause zap ineed needsme iuse usesme broken"; source "${script}"; echo "${opts}"))
		[[ "$COMPREPLY" ]] || COMPREPLY=(start stop restart zap)
		COMPREPLY=($(compgen -W "${COMPREPLY[*]}" "${cur}"))
	else
		COMPREPLY=($(compgen -o default "${cur}"))
	fi
	return 0
}
complete -F _gentoo_style_init /etc/init.d/*

Comment 4 Aaron Walker (RETIRED) gentoo-dev 2005-01-02 07:39:41 UTC
Gah, thought I had already commented on this bug and CC'd upstream...

Ed, can you think of a better way to do it w/o sourcing the rc scripts?  just seems like an icky way to go about doing it.
Comment 5 Ed Catmur 2005-01-10 18:32:44 UTC
(Sorry for the wait.)

Hmm.

Obviously we have to source something if we want to handle custom opts. It should work to replace in the above

  source "${script}"

with

  eval "$(grep '^opts=' "${script}")"

Admittedly this is a little brittle but we don't expect initscripts to be true bash scripts (read the monstrosity that is cachedepends.awk).

#
# completion for Gentoo style init
#
_gentoo_style_init()
{
	local script="${COMP_WORDS[0]}"
	local cur="${COMP_WORDS[$COMP_CWORD]}"

	if [[ ( -f "$script" || -h "$script" ) && -r "$script" ]] \
	&& [[ "$script" != *.sh ]] \
	&& [[ "$(head -n 1 "$script")" = "#!/sbin/runscript" ]]; then
		[[ "$COMP_CWORD" -gt 1 ]] && return 1
		COMPREPLY=($(opts="start stop restart pause zap ineed needsme iuse usesme broken"; eval "$(grep '^opts=' "${script}")"; echo "${opts}"))
		[[ "$COMPREPLY" ]] || COMPREPLY=(start stop restart zap)
		COMPREPLY=($(compgen -W "${COMPREPLY[*]}" "${cur}"))
	else
		COMPREPLY=($(compgen -o default "${cur}"))
	fi
	return 0
}
complete -F _gentoo_style_init /etc/init.d/*
Comment 6 Aaron Walker (RETIRED) gentoo-dev 2005-01-12 03:35:16 UTC
Bah ok. I didn't realize what you were originally attempting to do.

Fixed.