1

Every time I run new virtual terminal, it starts with

bash: /usr/share/bash-completion/bash_completion: line 226: syntax error near unexpected token `}'
bash: /usr/share/bash-completion/bash_completion: line 226: `}'
kimifish@kimipc:~$ 

But the file bash_completion seems to be оk (sure it's not though). Sorry for those vertical bars, it's just vim tab highlight:

     ...
     186 # Assign variables one scope above the caller
     187 # Usage: local varname [varname ...] &&
     188 #        _upvars [-v varname value] | [-aN varname [value ...]] ...
     189 # Available OPTIONS:
     190 #     -aN  Assign next N values to varname as array
     191 #     -v   Assign single value to varname
     192 # Return: 1 if error occurs
     193 # See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
     194 _upvars()
     195 {
     196     if ! (( $# )); then
     197     |   echo "${FUNCNAME[0]}: usage: ${FUNCNAME[0]} [-v varname"\
     198     |   |   "value] | [-aN varname [value ...]] ..." 1>&2
     199     |   return 2
     200     fi
     201     while (( $# )); do
     202     |   case $1 in
     203             -a*)
     204     |   |   |   # Error checking
     205     |   |   |   [[ ${1#-a} ]] || { echo "bash: ${FUNCNAME[0]}: \`$1': missing"\
     206     |   |   |   |   "number specifier" 1>&2; return 1; }
     207     |   |   |   printf %d "${1#-a}" &> /dev/null || { echo "bash:"\
     208     |   |   |   |   "${FUNCNAME[0]}: \`$1': invalid number specifier" 1>&2
     209     |   |   |   |   return 1; }
     210     |   |   |   # Assign array of -aN elements 
     211     |   |   |   [[ "$2" ]] && unset -v "$2" && eval $2=\(\"\${@:3:${1#-a}}\"\) &&
     212     |   |   |   shift $((${1#-a} + 2)) || { echo "bash: ${FUNCNAME[0]}:"\
     213     |   |   |   |   "\`$1${2+ }$2': missing argument(s)" 1>&2; return 1; }
     214     |   |   |   ;;
     215             -v) 
     216     |   |   |   # Assign single value
     217     |   |   |   [[ "$2" ]] && unset -v "$2" && eval $2=\"\$3\" &&
     218     |   |   |   shift 3 || { echo "bash: ${FUNCNAME[0]}: $1: missing"\
     219     |   |   |   "argument(s)" 1>&2; return 1; }
     220     |   |   |   ;;
     221             *)  
     222     |   |   |   echo "bash: ${FUNCNAME[0]}: $1: invalid option" 1>&2
     223     |   |   |   return 1 ;;
     224         esac
     225     done
     226 }
     ...

and I have absolutely no idea where to look for an error…

Part of my ~/.bashrc about bash-completion:

  91 if ! shopt -oq posix ; then
  92   if [ -f /usr/share/bash-completion/bash_completion ]; then
  93     . /usr/share/bash-completion/bash_completion
  94   elif [ -f /etc/bash_completion ]; then
  95     . /etc/bash_completion
  96   fi
  97 fi

Deleting code by parts revealed somewhat: cutting "while" loop eliminates the error, but cutting only "case" construction does not. =/

  • 1
    Is it possible that the file as some Microsoft CRLF line endings or other invisible characters? Check with sed -n l < the-file – Stéphane Chazelas Sep 4 '17 at 13:57
  • If you have absolutely no idea where to look for an error please consider leaving away parts of the function: Will it work without the while loop. If yes, just leave away single cases to narrow the problem and so on. – Philippos Sep 4 '17 at 14:31
  • 2
    The error may point to the last } of the file, but the thing that caused it may be in the beginning of it (which isn't shown here). – Kusalananda Sep 4 '17 at 14:33
  • One approach to debugging - copy the function to a file of its own (or build up the function in a file of its own) and in a new Bash, source that file alone; add/remove code until you find the cause. – Toby Speight Sep 4 '17 at 14:55
  • 1
    Do you have aliases for some bash keyword like done? – Stéphane Chazelas Sep 4 '17 at 15:59
2

One possible explanation is that you do

alias done='something'

prior to sourcing /usr/share/bash-completion/bash_completion.

That would explain that error message as bash would complain about the function being closed while the while loop hasn't (because of the missing done that was replaced by something).

Don't use done or any shell keyword as an alias name (though you could define some instrumenting aliases like alias do='do ((loop_level++));'; alias done='((loop_level--)); done' as long as they keep the shell structure).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.