Frequentemente, ao alternar meu usuário por root com su -
, recebo bash
mensagens de erro estranhas no rxvt
console, ou mesmo em um TTY. Elas acontecem mesmo após uma atualização completa do sistema do zero, então provavelmente é algo no root
HOME.
Por exemplo, estes:
sh: error importing function definition for `_file'
sh: _file: line 3: syntax error near unexpected token `('
sh: _file: line 3: ` --help | --version | --separator | -!(-*)[vF])'
Quando faço logout, recebo vários erros como:
/bin/bash: _sudo: line 19: syntax error near unexpected token `('
/bin/bash: _sudo: line 19: ` --user | --other-user | -!(-*)[uU])'
/bin/bash: error importing function definition for `_sudo'
Mesmo que eu faça sh
no console eu recebo
/bin/bash: _file: line 3: syntax error near unexpected token `('
/bin/bash: _file: line 3: ` --help | --version | --separator | -!(-*)[vF])'
/bin/bash: error importing function definition for `_file'
Então eu saio e entro novamente, e o comportamento normal é restaurado. Até que começa a se comportar estranhamente...
Achei que fosse um problema com '~/.bashrc' ou algo parecido, mas esses arquivos são compartilhados com meu usuário normal, que nunca mostra erros no console.
Obviamente há um bash
script com erros, mas não sei nem por onde começar a procurar. O que é _sudo
?? Os comandos grep _sudo $(find . -type f)
e find . -name _sudo
não mostram nada...
EDITAR
Este é o conteúdo do meu arquivo /usr/share/bash-completion/completions/sudo
:
# bash completion for sudo(8) -*- shell-script -*-
_sudo()
{
local cur prev words cword split
_init_completion -s || return
local i mode=normal
[[ $1 == *sudoedit ]] && mode=edit
[[ $mode == normal ]] &&
for ((i = 1; i <= cword; i++)); do
if [[ ${words[i]} != -* ]]; then
local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin
local root_command=${words[i]}
_command_offset $i
return
fi
if [[ ${words[i]} == -@(!(-*)e*|-edit) ]]; then
mode=edit
break
fi
[[ ${words[i]} == \
-@(user|other-user|group|close-from|prompt|!(-*)[uUgCp]) ]] &&
((i++))
done
case "$prev" in
--user | --other-user | -!(-*)[uU])
COMPREPLY=($(compgen -u -- "$cur"))
return
;;
--group | -!(-*)g)
COMPREPLY=($(compgen -g -- "$cur"))
return
;;
--close-from | --prompt | -!(-*)[Cp])
return
;;
esac
$split && return
if [[ $cur == -* ]]; then
local opts=$(_parse_help "$1")
COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur"))
[[ ${COMPREPLY-} == *= ]] && compopt -o nospace
return
fi
if [[ $mode == edit ]]; then
_filedir
fi
} &&
complete -F _sudo sudo sudoedit
# ex: filetype=sh
Para responder à pergunta formalmente, e como mencionado por @steeldriver nos comentários,
_sudo
o nome da função está no arquivo conclusions/sudo dobash-completion
projeto.As mensagens de erro fornecidas aparecem quando um ponto ou
source
utilitário é tentado com esse arquivo como argumento, de dentro do Bash com a opçãoextglob
unset, que é o padrão¹. Isso acontece porque a linha 19 contém os operadores de correspondência de padrões estendidos@()
e!()
:No entanto, como @Stéphane Chazelas observou (veja nota de rodapé), operadores de correspondência de padrões estendidos devem funcionar
[[ ... ]]
no lado direito==
desde o Bash 4.1, então essa pode não ser a fonte real do problema. De acordo com a mensagem de erro fornecida, a linha problemática parece ser a linha 29 :Da mesma forma,
!()
é usado no arquivo conclusions/file :Aqui está o exemplo de uso do utilitário dot com o caminho do arquivo do OpenBSD (a localização exata pode variar em outros sistemas):
Um comando como o acima provavelmente está contido em um dos arquivos de inicialização ou nos scripts chamados a partir deles.
A opção
-
(obsoleta) instrui su(1) a executar o shell (de acordo com os comentários, Bash) do usuário em questão (sem argumentos, root) como um shell de login (interativo).Quando executado como um shell de login interativo , o Bash obtém /etc/profile e, depois desse arquivo, o primeiro arquivo existente da lista a seguir, em ordem:
Para o usuário root, substitua
~
por/root
:Junto com /etc/profile , esses são os arquivos para verificar a origem do arquivo conclusions/sudo . Uma linha
deve ser adicionado a esse arquivo, antes do fornecimento de conclusions/sudo .
Observação: isso pode afetar a segurança, pois permite que o shell do root use o globbing estendido , que de outra forma estaria desativado.
¹ Nota de @Stéphane Chazelas: Desde o bash 4.1,
extglob
os operadores (um subconjunto dos operadores glob estendidos do ksh) estão disponíveis em[[...]]
operadores de correspondência de padrões, independentemente de a opção estar habilitada globalmente ou não.