Perché sudo ignora gli alias?


22

Sto eseguendo Ubuntu 10.04 e lo uso upstartper la gestione dei demoni. La mia applicazione aziendale viene eseguita come demone e deve essere eseguita come root a causa di vari privilegi. Per esempio:

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

Vorrei introdurre un aliasabbreviazione di questi comandi come qualcosa del tipo:

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

ed eseguirlo come startappe quello funziona ma preferirei non avere sudo nell'alias.

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

non quando viene eseguito utilizzando sudo startapp, il ritorno sudo: startapp: command not found.

Tuttavia, quando ho aggiunto l'alias:

alias sudo='sudo '

sudo startapp ora funziona ma sono ancora curioso di sapere perché sudo ignora gli alias.


Hai corso source ~/.bashrc? Questo aggiorna il file .bashrc e rende disponibili i nuovi alias?
manu,

@manu Sì, l'ho fatto
anfibio il

Risposte:


35

Vedo le informazioni di seguito da qui .

Quando usi sudo, usa l'espansione alias (altrimenti sudo ignora i tuoi alias)

alias sudo='sudo '

Il motivo per cui non funziona è spiegato qui .

Bash controlla solo la prima parola di un comando per un alias, le eventuali parole successive non vengono controllate. Ciò significa che in un comando come sudo ll, solo la prima parola (sudo) viene controllata da bash per un alias, ll viene ignorato. Possiamo dire a bash di controllare la parola successiva dopo l'alias (cioè sudo) aggiungendo uno spazio alla fine del valore di alias.


6

Gli alias e le funzioni sono definiti in una shell. Sudo è un programma esterno. Quindi sudo non vede alias, funzioni o builtin della shell, ma solo comandi esterni.

Gli alias sono pensati per essere nomi di comandi alternativi, quindi le shell li espandono solo nella posizione di comando, non quando sono argomenti per i comandi. Zsh supporta gli alias globali, che vengono espansi in qualsiasi punto della riga di comando e che possono essere utilizzati con parsimonia poiché esiste il rischio di espanderli accidentalmente anche in contesti in cui l'alias non ha senso.

Si può dire sudo per invocare una shell: sudo sh -c '…shell command here…'. I tuoi soliti alias non saranno disponibili all'interno di quel comando di shell, tuttavia, poiché sono normalmente memorizzati in un file come ~/.bashrco ~/.zshrcche viene letto solo da shell interattive.

alias sudo='sudo ', come proposto da Ramesh , fa sì che la shell espanda gli alias dopo sudo.


1
Fa il alias sudo='sudo 'lavoro per ZSH come bene?
CMCDragonkai,


1

Una soluzione per utenti zsh

In entrambi bash e zsh, la fine di un alias con uno spazio provocherà l'espansione della parola successiva da parte della shell. Ciò consente a qualcosa di simile al seguente di espandersi aliasmyalias

alias 'sudo=sudo '
sudo myalias

Sfortunatamente questo cade a pezzi quando hai più di una parola nel tuo alias (come sudo -u someone. Tuttavia, puoi abusare della funzione "alias globali" zsh per espandere manualmente gli alias in qualsiasi punto del comando.

alias -g '$= '

Questo crea un alias globale chiamato $(puoi usare qualsiasi parola tu voglia) che termina in uno spazio. Questo fa sì che zsh espanda la parola successiva come alias di comando regolare. Poiché l'alias si espande negli spazi bianchi, non verrà trattato come argomento. Ciò consente al seguente di funzionare.

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

Puoi anche usare $più volte su una riga di comando se hai un annidamento complicato dei comandi. Ho trovato questo abbastanza utile da avere un posto permanente nel mio zshrc, tuttavia l'alias è abbastanza semplice da definire quando è necessario utilizzarlo.


0

Ho appena dato una risposta alternativa qui senza ridefinire sudocon un alias.

Nel tuo caso sarebbe:

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

Tutto in una riga, nessun guscio extra, nessuna ridefinizione alias. ;-)


Oh aspetta un attimo - ho capito - stai usando xargsper eliminare le virgolette e grep per eliminare il comando =. Un po 'intelligente, ma probabilmente non necessario. eval "sudo $(alias aliasname | cut -d= -f2-)"è probabilmente migliore: xargsnon gestirà sempre correttamente le virgolette e potrebbe essercene più di una =all'interno.
Mikeserv,

@mikeserv Mi dispiace che tu non l'abbia capito ;-) xargsnon toglie le virgolette. È grep che prende il comando risolto tra le virgolette. Sai type -a alias_namerestituisce qualcosa di simile alias_name is aliased to command_within_quotes. Dal modo in cui ho cercato il vostro comando e non ha funzionato sul mio ubuntu :-( E 'il ritorno di. type -aDiversa tra le versioni di Linux (ne dubito)?.
loved.by.Jesus

So cosa typefa - in bash. Capisci però che le virgolette sono raddoppiate, giusto? Hai provato con un alias che conteneva virgolette singole? Ad ogni modo, hai ragione sul fatto che la mia cosa non funziona: hai bisogno di eval "sudo sh -c "$(...o eval "'sudo $(alias alias_name| cut -d\' -f2-)". Il fatto è che aliassono fondamentalmente predisposti eval: l' aliasutilità è specificata per produrre il loro contenuto in modo che possa essere ripristinata in modo sicuro sulla shell. Immagino che il tuo xargssia implementato quindi per appiattire lo spazio bianco? Stai solo attento, ok?
Mikeserv,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.