Bash script with user defined functions in autocom

2019-05-12 03:34发布

问题:

I need my bash script to get function names from user. The script should assist the users by auto completing the functions defined inside the same bash script file.

Eg:

myBash.sh

#!/usr/bash
function func1()
{
    echo "In func1 func"
}

function func2()
{
    echo "In func2 func"
}

function myFunc1()
{
    echo "In myFunc1 func"
}

while [ 1 ]
do
    echo -n "cmd>"
    read $userCmd
    $userCmd
done

]$ ./mybash.sh
cmd> my<tab><tab>
myFunc1

cmd> func<tab><tab>
func1 func2

This is my required output. How to accompany this?

回答1:

This workaround should do the trick.

#!/bin/bash

func1() {
    echo "You are in func1: $@"
}

func2() {
    echo "You are in func2: $@"
}

myFunc1() {
    echo "You are in myFunc1: $@"
}

#use: autocomplete "word1 word2 ..."
autocomplete() {
     #we only try to autocomplete the last word so we keep a record of the rest of the input
     OTHER_WORDS="${READLINE_LINE% *} " 
     if [[ ${#OTHER_WORDS} -ge ${#READLINE_LINE} ]]; then #if there is only 1 word...
         OTHER_WORDS="" 
     fi

     #the -W flag tells compgen to read autocomplete from the 1st argument provided
     #we then evaluate the last word of the current line through compgen
     AUTOCOMPLETE=($(compgen -W $1 "${READLINE_LINE##* }"))
     if [[ ${#AUTOCOMPLETE[@]} == 1 ]]; then #if there is only 1 match, we replace...
        READLINE_LINE="$OTHER_WORDS${AUTOCOMPLETE[0]} "
        READLINE_POINT=${#READLINE_LINE}     #we set the cursor at the end of our word
     else
        echo -e "cmd> $READLINE_LINE\n${AUTOCOMPLETE[@]}" #...else we print the possibilities
     fi
}

MYFUNC="func1 func2 myFunc1" #here we list the values we want to allow autocompletion for
set -o emacs     #we do this to enable line edition
bind -x '"\t":"autocomplete \$MYFUNC"';   #calls autocomplete when TAB is pressed
while read -ep "cmd> "; do
    history -s $REPLY    #history is just a nice bonus
    eval ${REPLY}
done

To try it :

]$ ./mybash.sh
cmd> my<tab>
cmd> myFunc1

cmd> func<tab>
func1 func2

cmd> func1 hello, world!
You are in func2: hello, world!

cmd> func1 my<tab>
cmd> func1 myFunc1

As mentioned in my previous comment, have a look at this question. It uses a nice trick to auto detect all inner functions in order to use it as auto-complete values.



标签: linux bash shell