bash(1)
chamará a função command_not_found_handle()
se definido e o comando a ser executado não for encontrado. Se você ainda não estiver usando esse recurso (como o pacote command-not-found no Ubuntu), você pode usá-lo para retirar o sinal de dois pontos e tentar novamente:
command_not_found_handle() {
if [[ "${1:0:1}" != : ]]; then
printf "%s: %s: command not found\n" "$0" "$1" >&2
return 127
else
"${1/#:}" "${@:2}"
fi
}
Coloque essa função no seu .bashrc
. Então, quando um comando que começa com dois pontos não for encontrado, ele tirará o cólon da frente e tentará novamente.
Edit: Vou explicar um pouco mais, já que há algumas expansões incomuns aqui.
Em primeiro lugar, conforme observado nos comentários, command_not_found_handle
é um recurso do bash 4. Bash 4 foi lançado em fevereiro de 2009. A função command_not_found_handle
é chamada com argumentos que é o comando não encontrado e os argumentos desse comando. ou seja, $1
é o comando não encontrado e $2
em diante são os argumentos para o comando que não foi encontrado. Isso é descrito em COMANDO EXECUÇÃO na página man.
"${1:0:1}"
é uma expansão que recebe uma substring de $1
, da posição 0 de comprimento 1. Ou seja, extrai o primeiro caractere de $1
, em que $1
é o comando que não foi encontrado. Isso está documentado em Expansão do Parâmetro na página man como ${parameter:offset:length}
.
Se o primeiro caractere de $1
não for dois pontos, imprimimos um erro e retornamos com um valor de saída 127. 127 é o código de saída que o bash usa quando não encontra o comando para executar conforme documentado em EXECUÇÃO DE COMANDO na página man.
"${1/#:}"
expande para $1
com qualquer cólon inicial removido. Se não houver cólon no início, isso equivale a um $1
simples, mas sabemos que ele começa com dois pontos de qualquer maneira devido à ramificação da condição em que estamos. Essa expansão está documentada em Expansão do Parâmetro na página man na seção ${parameter/pattern/string}
.
"${@:2}"
expande para os parâmetros posicionais a partir do segundo. Essa expansão está documentada em Expansão do Parâmetro na página man na seção ${parameter:offset}
, como um caso especial para matrizes e @
. Ou seja, em vez de extrair uma substring, ela se expande para elementos da matriz.
O resultado final é que, se um comando não encontrado for executado e tiver dois pontos à esquerda, removeremos os dois pontos para formar um novo comando e passaremos os argumentos originais para o novo comando. Isso terminará funcionando recursivamente, como se a segunda tentativa de executar um comando não fosse encontrada, command_not_found_handle()
será executado novamente. Isso significa que você pode executar :::mkdir
e ainda vai acabar executando mkdir
.