A parte chave neste comportamento é explicada por 2 bits na página de manual bash:
Na seção HISTORY EXPANSION
:
History expansion is performed immediately after a complete line is read, before the shell breaks it into words.
Na seção ALIASES
:
The first word of each simple command, if unquoted, is checked to see if it has an alias.
Portanto, basicamente, a expansão do histórico ocorre antes da divisão de palavras. A expansão do alias ocorre depois.
Solução alternativa
A melhor maneira que posso pensar em fazer isso é o seguinte:
alias root='sudo $(fc -ln -1)'
Isso funcionará para comandos simples, mas para comandos mais complexos, precisamos ajustá-lo.
alias root='sudo sh -c "$(fc -ln -1)"'
O motivo da mudança é por causa de algo assim:
# alias root='sudo $(fc -ln -1)'
# echo "I AM $(whoami)"
I AM patrick
# root
"I AM $(whoami)"
Como você pode ver, nenhuma análise de shell é feita. Ao alterá-lo para usar sh -c "..."
, ele faz a interpretação da shell.
# alias root='sudo sh -c "$(fc -ln -1)"'
# echo "I AM $(whoami)"
I AM patrick
# root
I AM root
.
Outra maneira (eu pensei nisso primeiro, então mantenha-o na resposta, mas não é tão bom quanto o acima):
alias root='fc -e "sed -i -e \"s/^/sudo /\""'
O comando fc -e
executará o comando especificado passando um arquivo contendo o comando executado anteriormente. Apenas executamos sed
nesse arquivo para prefixar o comando com sudo
.