Por que o sudo ignora aliases?

22

Estou executando o Ubuntu 10.04 e uso upstartpara gerenciamento de daemon. Meu aplicativo corporativo é executado como um daemon e deve ser executado como root devido a vários privilégios. Por exemplo:

sudo start my-application-long-ID
sudo stop my-application-long-ID
etc

Gostaria de apresentar um aliaspara abreviar esses comandos como algo como:

alias startapp='sudo start my-application-long-ID'

e executá-lo como startappe que funciona, mas eu preferiria não ter sudo no alias.

alias startapp='start my-application-long-ID'

não ao executar usando sudo startapp, retornando sudo: startapp: command not found.

No entanto, quando adicionei o alias:

alias sudo='sudo '

sudo startapp agora funciona, mas ainda estou curioso por que o sudo ignora aliases.

anfíbio
fonte
A sua corrida source ~/.bashrc? Isso atualiza o arquivo .bashrc e disponibiliza os novos aliases?
manu
@manu Sim, eu fiz
amphibient
1
serverfault.com/questions/61321/how-to-pass-alias-through-sudo
Ciro Santilli新疆改造中心法轮功六四事件

Respostas:

35

Eu vejo as informações abaixo daqui .

Ao usar o sudo, use expansão de alias (caso contrário, o sudo ignora seus aliases)

alias sudo='sudo '

A razão pela qual não funciona é explicada aqui .

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 é ignorado. Podemos dizer ao bash para verificar a próxima palavra após o alias (por exemplo, sudo) adicionando um espaço ao final do valor do alias.

Ramesh
fonte
6

Aliases e funções são definidos em um shell. Sudo é um programa externo. Portanto, o sudo não vê aliases, funções ou embutidos no shell, apenas comandos externos.

Os aliases devem ser nomes de comandos alternativos; portanto, os shells os expandem apenas na posição de comando, não quando são argumentos para comandos. O Zsh suporta aliases globais, que são expandidos em qualquer lugar na linha de comando, e é melhor usar com moderação, pois existe o risco de expandi-los acidentalmente, mesmo em contextos em que o alias não faz sentido.

Você pode dizer sudo para invocar um shell: sudo sh -c '…shell command here…'. Seus aliases habituais não estarão disponíveis dentro desse comando shell, no entanto, uma vez que normalmente são armazenados em um arquivo como ~/.bashrcou ~/.zshrcque é lido apenas por shells interativos.

alias sudo='sudo ', como proposto por Ramesh , faz com que o shell expanda os aliases depois sudo.

Gilles 'SO- parar de ser mau'
fonte
1
O alias sudo='sudo 'trabalho para ZSH também?
CMCDragonkai # 13/16
2
@CMCDragonkai Yes
Gilles 'SO- stop
1

Uma solução para usuários zsh

No bash e no zsh, encerrar um alias com um espaço fará com que o shell alias expanda a próxima palavra. Isso permite que algo como o seguinte alias expandamyalias

alias 'sudo=sudo '
sudo myalias

Infelizmente, isso se desfaz quando você tem mais de uma palavra no seu alias (como sudo -u someone. No entanto, você pode abusar do recurso "aliases globais" do zsh para expandir manualmente os aliases em qualquer lugar do comando.

alias -g '$= '

Isso cria um alias global chamado $(você pode usar qualquer palavra que desejar) que termina em um espaço. Isso faz com que o zsh expanda a próxima palavra como um alias de comando regular. Como o alias se expande para espaços em branco, não será tratado como argumento. Isso permite que o seguinte funcione.

% alias myalias=echo
% sudo -u someone myalias foo
sudo: myalias: command not found
% sudo -u someone $ myalias foo
foo

Você pode até usar $várias vezes em uma linha de comando se tiver um aninhamento de comando complicado. Eu achei isso útil o suficiente para que ele tenha um lugar permanente no meu zshrc, no entanto, o alias é simples o suficiente para definir quando você precisa usá-lo.

Kevin Cox
fonte
0

Eu apenas dei uma resposta alternativa aqui sem redefinir sudocom um alias.

No seu caso, seria:

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

Tudo em uma linha, sem conchas extras, sem redefinições de alias. ;-)

Jesus amado
fonte
Oh, espere um minuto - entendi - você está usando xargspara retirar as aspas e grep para retirar a liderança =. Meio inteligente, mas provavelmente desnecessário. eval "sudo $(alias aliasname | cut -d= -f2-)"provavelmente é melhor - xargsnem sempre manipulará as aspas corretamente e poderá haver mais de uma =.
mikeserv
@ MikeServ Lamento que você não entendeu ;-) xargsnão retira as aspas. É grep quem recebe o comando resolvido entre as aspas. Você sabe que type -a alias_nameretorna algo como alias_name is aliased to command_within_quotes. Pelo jeito que eu tentei o seu comando e não funcionou no meu ubuntu :-( É o retorno de. type -aDiferente entre as versões Linux (eu duvido)?.
loved.by.Jesus
Eu sei o que typefaz - dentro bash. Você entende, porém, que as aspas são duplicadas, certo? Você já tentou com um alias que continha aspas simples? Enfim, você está certo sobre o meu negócio não funcionar - você precisa eval "sudo sh -c "$(...ou eval "'sudo $(alias alias_name| cut -d\' -f2-)". O problema é que eles aliassão basicamente pré-arranjados eval- o aliasutilitário deve exibir seu conteúdo para que possa ser reinicializado com segurança no shell. Eu acho que o seu xargsé implementado, em seguida, para achatar o espaço em branco? Apenas tenha cuidado com isso, ok?
mikeserv