Aliases não disponíveis ao usar o sudo

161

Hoje eu estava brincando com aliases e notei que os aliases não parecem estar disponíveis enquanto estiver usando sudo:

danny@kaon:~$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

danny@kaon:~$ ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //

danny@kaon:~$ sudo -i
root@kaon:~# ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //
root@kaon:~# exit
logout

danny@kaon:~$ sudo ll -d /
sudo: ll: command not found

Existe alguma razão pela qual você não pode usar aliases enquanto estiver usando sudo?

kemra102
fonte
Você declarou esses aliases em .bashrc em / root /
Luciano Facchinelli
2
@LucianoFacchinelli: /root/.bashrcnão é lido ao executar um comando através do sudo.
Flimm
serverfault.com/questions/61321/how-to-pass-alias-through-sudo
Ciro Santilli新疆改造中心法轮功六四事件
@Limlim: o que dizer sudo -i?
Evi1M4chine

Respostas:

251

Adicione a seguinte linha ao seu ~/.bashrc:

alias sudo='sudo '

No manual do bash :

Os aliases permitem que uma sequência seja substituída por uma palavra quando é usada como a primeira palavra de um comando simples. O shell mantém uma lista de aliases que podem ser definidos e desabilitados com os comandos internos de alias e unalias.

A primeira palavra de cada comando simples, se não estiver entre aspas, é verificada para ver se ele possui um alias . Nesse caso, essa palavra é substituída pelo texto do alias. Os caracteres '/', '$', '' ',' = 'e qualquer um dos metacaracteres do shell ou caracteres de citação listados acima podem não aparecer em um nome alternativo. O texto de substituição pode conter qualquer entrada válida do shell, incluindo metacaracteres do shell. A primeira palavra do texto de substituição é testada para aliases, mas uma palavra idêntica a um alias sendo expandido não é expandida uma segunda vez. Isso significa que se pode, por exemplo, ls a "ls -F", por exemplo, e o Bash não tenta expandir recursivamente o texto de substituição. Se o último caractere do valor do alias for um caractere de espaço ou tabulação, a próxima palavra de comando após o alias também será verificada quanto à expansão do alias .

(Ênfase minha).
O Bash verifica apenas a primeira palavra de um comando em busca de um alias; quaisquer palavras depois disso não são verificadas. Isso significa que em um comando como sudo ll, apenas a primeira palavra ( sudo) é verificada pelo bash para um alias, llé ignorada. Podemos dizer ao bash para verificar a próxima palavra após o alias (ie sudo), adicionando um espaço ao final do valor do alias.

Isaías
fonte
18
Solução bastante agradável.
ulidtko
Então, basicamente, a questão se resume ao fato de que o sudo é simplesmente programado de tal maneira que não verifica o apelido, portanto, o ll não foi encontrado?
precisa saber é o seguinte
2
A leitura da documentação, obviamente, beneficia um lote inteiro :-)
biocyberman
4
Isso será interrompido se eu usar uma bandeira sudo, por exemplo sudo -H ll?
Mark E. Haase
1
@ mehaase Sim, eu tentei e ele quebra.
user31389
5

Eu escrevi uma função Bash para ela que sombreia sudo.

Ele verifica se eu tenho um alias para o comando fornecido e executa o comando alias em vez do literal sudonesse caso.

Aqui está minha função como one-liner:

sudo() { if alias "$1" &> /dev/null ; then $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}" ; else command sudo $@ ; fi }

Ou bem formatado:

sudo() { 
    if alias "$1" &> /dev/null ; then 
        $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}"
    else 
        command sudo "$@"
    fi 
}

Você pode anexá-lo ao seu .bashrcarquivo, não se esqueça de fonte ou reinicie a sessão do terminal posteriormente para aplicar as alterações.

Byte Commander
fonte
Seria maravilhoso se isso também funcionasse para o sudo -H ll.
UAV
3

Os aliases são específicos do usuário - você precisa defini-los em /root/.bashrc

Ragnar123
fonte
3
Eles já estão sob /root/.bashrc modo que não é um problema
kemra102
1
Essa resposta só seria correto para a situação quando você está correndo o próprio shell como root, como com sudo -sou sudo -i(e única , se executado por si só para obter uma shell de root, não com os sudo -s command...ou sudo -i command...formas) ou sudo bashou sudo suou a situação onde você ativou logins raiz e tem um shell raiz dessa maneira. Quando um usuário não raiz executa a sudo command...partir de seu próprio shell, a expansão do alias é feita por seu próprio shell não raiz. sudonão expande aliases; portanto, conforme aplicada à situação descrita na pergunta , essa resposta está incorreta.
Eliah Kagan
3

A resposta do @Alvins é a mais curta. Sem dúvida! :-)

No entanto, pensei em uma solução de linha de comando para executar um comando com alias no sudo, onde não há necessidade de redefinir sudocom um aliascomando.

Aqui está minha proposta para aqueles a quem possa interessar:

Solução

type -a <YOUR COMMAND HERE> | grep -o -P "(?<=\`).*(?=')" | xargs sudo

Exemplo

No caso do llcomando

type -a ll | grep -o -P "(?<=\`).*(?=')" | xargs sudo

Explicação

quando você tem um alias (como:), llo comando type -aretorna a expressão alias:

$type -a ll
ll is aliased to `ls -l'

com grepvocê seleciona o texto entre o acento `e apóstrofo 'nesse casols -l

E xargsexecuta o texto selecionado ls -lcomo parâmetro de sudo.

Sim, um pouco mais, mas completamente limpo ;-) Não há necessidade de redefinir sudocomo alias.

Jesus amado
fonte
3
Pode ser mais simples se você usou o aliasbuilt-in, já que sua saída é mais limpa. alias llsaídas alias ll='ls -ahlF'.
Muni
Aqui está a versão incorporando sugestão de @ Muru: alias ll | sed "s/.*'\(.*\)'.*/\1/g" | xargs sudo.
ACK_stoverflow
Eu acho que o objetivo da pergunta original era salvar o trabalho, não sendo necessário sudo -iprimeiro, executar o comando alias, mas fazê-lo imediatamente. Ter um comando tão complexo derrota isso. Você poderia fazer o primeiro e ser muito mais rápido.
Evi1M4chine
1

Eu tenho outra solução interessante, que adiciona um pouco de confiança também:

Use a conclusão do bash para substituir automaticamente as palavras por trás sudopor seus aliases ao pressionar tab.

Salve isso como /etc/bash_completion.d/sudo-alias.bashcompe ele deve ser carregado automaticamente na inicialização interativa do shell:

_comp_sudo_alias() { from="$2"; COMPREPLY=()
  if [[ $COMP_CWORD == 1 ]]; then
    COMPREPLY=( "$( alias -p | grep "^ *alias $from=" | sed -r "s/^ *alias [^=]+='(.*)'$/\1/" )" )
    return 0
  fi
  return 1
}
complete -o bashdefault -o default -F _comp_sudo_alias sudo

Em seguida, faça login em um novo terminal e você deve estar pronto.

Evi1M4chine
fonte
Há uma maneira de obter uma lista de aliases, especialmente destinado para a conclusão:compgen -a
Muru
@ muru: Obrigado, mas neste caso eu preciso dos valores, não das chaves. Portanto, o alias que foi inserido será substituído por. Você digita o alias (como em sudo ll), pressiona [TAB] e o script encontra llna lista de atribuições de alias, corta o que é atribuído a ele e o insere. (Então você deseja obter por exemplo sudo ls -lahvF --color=auto --time-style=long-iso.)
Evi1M4chine
0

Eu tenho uma solução diferente na qual você não precisa adicionar sudocomo um alias. Eu corro o Linux Mint 17.3, mas deve ser bastante semelhante ao Ubuntu.

Quando você é root, ele .profileé executado a partir do diretório inicial. Se você não souber qual é o diretório inicial no diretório raiz, poderá verificar com:

sudo su
echo $HOME

Como você pode ver, o lar de rooté /root/. Verifique seu conteúdo:

cd $HOME
ls -al

Deve haver um .profilearquivo. Abra o arquivo e adicione as seguintes linhas:

if [ "$BASH" ]; then
    if [ -f ~/.bash_aliases];then
        . ~/.bash_aliases 
    fi
fi

Basicamente, o que esse script bash faz é procurar um arquivo chamado .bash_aliases. Se os arquivos estiverem presentes, ele executará o arquivo.

Salve o .profilearquivo e crie seus aliases em .bash_aliases. Se você já tiver o arquivo de aliases pronto, copie o arquivo para este local

Reinicie o terminal e você está pronto!

Karthik Ramakrishnan
fonte
0

A resposta mais votada é ótima. No entanto, se você digitar sudo -ie elevar para um prompt do sudo ( #), não terá os aliases que deseja usar.

Para utilizar seus aliases (e tudo mais) no #prompt, use:

sudo cp "$PWD"/.bashrc /root/.bashrc

Onde "$ PWD" é expandido automaticamente para "/ home / YOUR_USER_NAME"

WinEunuuchs2Unix
fonte
0

@ WinEunuuchs2Unix: $PWDexpande para o "diretório de trabalho atual". Eu acho que você quer $HOME.

Além disso, na maioria das situações, é provavelmente melhor ter um arquivo .bashrc raiz separado. Na verdade, eu o tornaria um arquivo real /root, um link direto para ele no diretório inicial do usuário (por exemplo, .bashrc_root) e o originaria do .bashrcarquivo do usuário . Se, posteriormente, essa conta de usuário privilegiada não estiver mais presente, o .bashrcarquivo raiz ainda estará disponível para outros usuários.

Shaun Griffith
fonte