[Bash-completion-devel] Bug#733815: Modules completion takes a very long time

Linda Walsh bash at tlinx.org
Wed Jan 1 22:05:35 UTC 2014



auil at usp.br wrote:
>>  Another issue is that some filenames have '-' in them, but the module
>>  names have '_' in them.
> 
> This is a problem because the modules filenames are a mess. Some
> filenames have an underscore '_' too.
----

> If you want to get
> 
> (all available mods) minus (already loaded mods)
> 
> a solution is to change hyphen '-' to underscore '_' in the filenames,
> but not the opposite. This is because the output of "lsmod" or
> "/proc/modules" is always with underscore.
----

I wasn't sure that would always be so, since I thought the module name
was a text string, not a 'C' expression.   So to protect against
either case (i.e. - in /proc/modules, for example), my new_mods function
already handled that case.

Actually I left some dead code in there as well (the refs to ld2):


Should be:
#!/bin/bash

function _clean_n_sort_mods {
	declare -a mods
	readarray mods < <(echo "$(find /lib/modules/$(uname -r) -name \*.ko)")
	mods=("${mods[@]##*/}")
	echo "${mods[@]//.ko/}"
}

function _loaded_mods {
	awk '{print $1}' /proc/modules
}

function _newmods {
	declare cur prev words cword
	_get_comp_words_by_ref cur
	declare -a ldm ld1 ldup unloaded replies
	readarray ldm< <(_loaded_mods)
	#spacey kernel-hacker special; for those forgetting '-' != '_ui
	readarray ld1< <(echo "${ldm[@]//_/-}" "${ldm[@]//-/_}")
	readarray ldup< <(echo "${ld1[@]}" "${ld1[@]}")
	readarray unloaded< <(_clean_n_sort_mods)
	readarray lines< <(echo "${ldup[@]}" "${unloaded[@]}")
	readarray -t replies< <(echo "${lines[@]}"|tr -d " "|grep -Pv '^\s*$'|sort|uniq -u)

	COMPREPLY=( $(compgen -W "$(echo "${replies[@]}")" -- "$cur" ) )
}

complete -F _newmods modprobe
-----------------------------------------

Note -- changed the _loaded_mods to use the awk you suggested.

Why do you run it through sort... oh... use use those as negative expressions..
That's why...

when I switched out the "sort|uniq -u"   and put in sort -u, it no longer
worked.<<<<<

I handled the duplication differently in newmods...(and filtering out '-/_').

Using bash, I duplicated the arrays in ld1, one copy with the names spelled
with all '-' and the other copy with names all spelled '_'.

I combinded it with all the unloaded modules (which contains *both* '_' and '-'
for any modules that "mix it up" and combine that with my 2 special arrays.
Then use the sort and uniq -u to give me **only** the ones that were uniq --
so the ones that were already loaded under '-' and '_' (i.e. both) would be
filtered out.

i.e. check it out.. the above should give you the same number
of unloaded mods as your code...

Note that while _clean_n_sort_mods includes a blank line -- it is filtered
out in newmods, so:

_clean_n_sort_mods|wc
     409     408    4624
(got 409 lines but 408 modules)
_loaded_mods|wc
      32      32     343
(32 in memory)
but newmods gives:
# modprobe (complete)
Display all 376 possibilities?

i.e. 408-32 = 376

Thanks for the awk hint -- you can create the patterns like you do
or you can use use bash to dup the arrays and the |sort|uniq -u| to get
rid of the dups ...  likely either way works for this purpose...

I liked the bash-array usage rather than relying on a more
complex pattern in grep, but yours might be faster, cuz bash
can be slow... ;-)



More information about the Bash-completion-devel mailing list