Alias ​​non disponibili quando si utilizza sudo


161

Oggi stavo giocando con gli alias e ho notato che gli alias non sembrano essere disponibili durante l'utilizzo 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

C'è qualche motivo per cui non è possibile utilizzare gli alias durante l'utilizzo sudo?


Hai dichiarato quegli alias in .bashrc su / root /
Luciano Facchinelli il

2
@LucianoFacchinelli: /root/.bashrcnon viene letto quando si esegue un comando tramite sudo.
Flimm,


@Flimm: che dire sudo -i?
Evi1M4chine,

Risposte:


251

Aggiungi la seguente riga al tuo ~/.bashrc:

alias sudo='sudo '

Dal manuale di bash :

Gli alias consentono di sostituire una stringa con una parola quando viene utilizzata come prima parola di un semplice comando. La shell mantiene un elenco di alias che possono essere impostati e non impostati con i comandi integrati alias e unalias.

La prima parola di ogni semplice comando, se non quotata, viene controllata per vedere se ha un alias . In tal caso, tale parola è sostituita dal testo dell'alias. I caratteri '/', '$', '`', '=' e tutti i metacaratteri della shell o i caratteri di quotazione elencati sopra potrebbero non apparire in un nome alias. Il testo sostitutivo può contenere qualsiasi input di shell valido, inclusi i metacaratteri della shell. La prima parola del testo sostitutivo viene testata per gli alias, ma una parola identica a un alias in fase di espansione non viene espansa una seconda volta. Ciò significa che si può alias ls in "ls -F", per esempio, e Bash non tenta di espandere ricorsivamente il testo di sostituzione. Se l'ultimo carattere del valore alias è uno spazio o un carattere di tabulazione, anche la parola di comando successiva che segue l'alias viene controllata per l'espansione dell'alias .

(Enfasi mia).
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) è controllata da bash per un alias, llviene ignorata. Possiamo dire a bash di controllare la parola successiva dopo l'alias (cioè sudo) aggiungendo uno spazio alla fine del valore di alias.


18
Bella soluzione.
Ulidtko,

Quindi sostanzialmente il problema si riduce al fatto che sudo è semplicemente programmato in modo tale da non controllare l'alias, quindi non verrà trovato?
kemra102,

2
Leggere la documentazione ovviamente giova molto :-)
biocyberman,

4
Questo si romperà se uso un flag sudo, ad esempio sudo -H ll?
Mark E. Haase,

1
@mehaase Sì, ci ho provato e si rompe.
user31389

5

Ho scritto una funzione Bash per questo che ombre sudo.

Verifica se ho un alias per il comando dato ed esegue il comando alias invece di quello letterale con sudoin quel caso.

Ecco la mia funzione di one-liner:

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

O ben formattato:

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

Puoi aggiungerlo al tuo .bashrcfile, non dimenticare di cercarlo o riavviare la sessione del terminale in seguito per applicare le modifiche.


Sarebbe meraviglioso se questo funzionasse anche per sudo -H ll.
uav

3

Gli alias sono specifici dell'utente - è necessario definirli in /root/.bashrc


3
Sono già in /root/.bashrc quindi non è un problema
kemra102

1
Questa risposta sarebbe solo essere corretto per la situazione in cui si sta eseguendo la shell stessa come root, come con sudo -so sudo -i(e solo se eseguito da solo per ottenere una shell di root, non con le sudo -s command...o sudo -i command...forme) o sudo basho sudo su, o la situazione in cui si ho abilitato gli accessi root e hanno una shell root in quel modo. Quando un utente non root viene eseguito sudo command...dalla propria shell, l'espansione dell'alias viene eseguita dalla propria shell non root. sudonon espande di per sé gli alias, quindi , applicata alla situazione descritta nella domanda , questa risposta non è corretta.
Eliah Kagan,

3

La risposta di @Alvins è la più breve. Nessun dubbio! :-)

Tuttavia, ho pensato a una soluzione a riga di comando per eseguire un comando con alias in sudo in cui non è necessario ridefinire sudocon un aliascomando.

Ecco la mia proposta per coloro a cui potrebbe interessare:

Soluzione

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

Esempio

Nel caso del llcomando

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

Spiegazione

quando si dispone di un alias (come :) llil comando type -arestituisce l'espressione alias:

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

con grepte seleziona il testo tra l'accento `e l'apostrofo 'in quel casols -l

Ed xargsesegue il testo selezionato ls -lcome parametro di sudo.

Sì, un po 'più a lungo ma completamente pulito ;-) Non è necessario ridefinire sudocome alias.


3
Potrebbe essere più semplice se hai utilizzato l' aliasintegrato, poiché il suo output è più pulito. alias lluscite alias ll='ls -ahlF'.
Muru,

Ecco la versione incorpora il suggerimento di @ Muru: alias ll | sed "s/.*'\(.*\)'.*/\1/g" | xargs sudo.
ACK_stoverflow,

Penso che il punto della domanda originale fosse salvare il lavoro non dovendo sudo -iprima eseguire il comando con alias, ma farlo immediatamente. Avere un comando così complesso lo sconfigge. Potresti semplicemente fare il primo ed essere molto più veloce.
Evi1M4chine,

1

Ho un'altra bella soluzione, che aggiunge anche un po 'di fiducia:

Usa il completamento bash per sostituire automaticamente le parole dietro sudocon i loro alias quando premi tab.

Salvalo come /etc/bash_completion.d/sudo-alias.bashcomp, e dovrebbe essere caricato automaticamente all'avvio interattivo della 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

Quindi accedi a un nuovo terminale e dovresti essere pronto per partire.


C'è un modo per ottenere un elenco di alias, pensato soprattutto per il completamento:compgen -a
muru

@muru: Grazie, ma in questo caso ho bisogno dei valori, non delle chiavi. Quindi con quale alias inserito verrà sostituito. Digiti l'alias, (come in sudo ll), premi [TAB ↹] e lo script trova llnell'elenco delle assegnazioni di alias, ritaglia ciò che gli è assegnato e lo inserisce. (Quindi sudo ls -lahvF --color=auto --time-style=long-iso
otterresti

0

Ho una soluzione diversa per cui non è necessario aggiungere sudocome alias. Corro Linux Mint 17.3 ma dovrebbe essere abbastanza simile a Ubuntu.

Quando sei root, allora .profileviene eseguito dalla sua home directory. Se non sai quale sia la home directory in root, puoi verificare con:

sudo su
echo $HOME

Come puoi vedere, la casa di rootè /root/. Controlla il suo contenuto:

cd $HOME
ls -al

Dovrebbe esserci un .profilefile. Apri il file e aggiungi le seguenti righe:

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

Fondamentalmente, ciò che fa questo script bash è verificare la presenza di un file chiamato .bash_aliases. Se il file è presente, esegue il file.

Salva il .profilefile e crea i tuoi alias .bash_aliases. Se hai già pronto il file alias, copia il file in questa posizione

Riavvia il terminale e sei a posto!


0

La risposta più votata è ottima. Tuttavia, se digiti sudo -ied elevi a un prompt di sudo ( #) non avrai gli alias che ti piace usare.

Per utilizzare i tuoi alias (e tutto il resto) al #prompt, usa:

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

Dove "$ PWD" viene espanso automaticamente in "/ home / YOUR_USER_NAME"


0

@ WinEunuuchs2Unix: si $PWDespande nella "directory di lavoro attuale". Penso che tu voglia $HOME.

Inoltre, per la maggior parte delle situazioni, è probabilmente meglio avere un file .bashrc root separato. In effetti, lo trasformerei in un vero file /root, un soft link ad esso nella home directory dell'utente (ad esempio, .bashrc_root) e lo estrarrei dal .bashrcfile dell'utente . Se in un secondo momento questo account utente privilegiato non è più presente, il .bashrcfile root è ancora disponibile per altri utenti.

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.