Aliasy nie są dostępne podczas korzystania z sudo

159

Bawiłem się dziś z aliasami i zauważyłem, że aliasy nie są dostępne podczas używania 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

Czy jest jakiś powód, dla którego nie możesz używać aliasów podczas korzystania sudo?

kemra102
źródło
Czy zadeklarowałeś te aliasy w .bashrc w katalogu / root /
Luciano Facchinelli,
2
@LucianoFacchinelli: /root/.bashrcnie jest czytany podczas uruchamiania polecenia przez sudo.
Flimm
serverfault.com/questions/61321/how-to-pass-alias-through-sudo
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
@Flimm: A co z sudo -i?
Evi1M4chine

Odpowiedzi:

250

Dodaj następujący wiersz do ~/.bashrc:

alias sudo='sudo '

Z podręcznika bash :

Aliasy pozwalają na zastąpienie łańcucha słowem, gdy jest ono używane jako pierwsze słowo prostej komendy. Powłoka utrzymuje listę aliasów, które można ustawić i rozbroić za pomocą wbudowanych poleceń alias i unalias.

Pierwsze słowo każdego prostego polecenia, jeśli nie jest cytowane, jest sprawdzane pod kątem aliasu . Jeśli tak, to słowo jest zastępowane tekstem aliasu. Znaki „/”, „$”, „'”, „=” oraz dowolne metaznaki powłoki lub znaki cytowania wymienione powyżej mogą nie pojawiać się w nazwie aliasu. Tekst zastępczy może zawierać dowolne prawidłowe dane wejściowe powłoki, w tym metaznaki powłoki. Pierwsze słowo zamiennego tekstu jest testowane pod kątem aliasów, ale słowo, które jest identyczne z rozwijanym aliasem, nie jest rozszerzane po raz drugi. Oznacza to, że można na przykład użyć aliasu ls do „ls -F”, a Bash nie próbuje rekurencyjnie rozszerzać tekstu zastępczego. Jeśli ostatnim znakiem wartości aliasu jest znak spacji lub tabulacji, to następne słowo polecenia następujące po aliasie jest również sprawdzane pod kątem rozszerzenia aliasu .

(Podkreśl moje).
Bash sprawdza tylko pierwsze słowo polecenia pod kątem aliasu, a żadne słowa po nim nie są sprawdzane. Oznacza to, że w takim poleceniu sudo lltylko pierwsze słowo ( sudo) jest sprawdzane przez bash dla aliasu, lljest ignorowane. Możemy nakazać bashowi sprawdzenie następnego słowa po aliasie (tj. sudo) Poprzez dodanie spacji na końcu wartości aliasu.

Izajasza
źródło
18
Całkiem niezłe rozwiązanie.
ulidtko 17.01.11
Więc w zasadzie problem sprowadza się do tego, że sudo jest po prostu zaprogramowane w taki sposób, że nie sprawdza aliasu, więc nie można go znaleźć?
kemra102
2
Czytanie dokumentacji oczywiście przynosi wiele korzyści :-)
biocyberman
4
Czy to się zepsuje, jeśli użyję np. Flagi sudo sudo -H ll?
Mark E. Haase,
1
@mehaase Tak, próbowałem i psuje się.
user31389,
5

Napisałem dla niego funkcję Bash, która rzuca cień sudo.

Sprawdza, czy mam alias dla podanej komendy i uruchamia komendę aliasowaną zamiast literalnej sudow tym przypadku.

Oto moja funkcja jako jednej linijki:

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

Lub ładnie sformatowany:

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

Możesz dołączyć go do swojego .bashrcpliku, nie zapomnij o źródle lub zrestartuj sesję terminalową, aby zastosować zmiany.

Bajt Dowódca
źródło
Byłoby wspaniale, gdyby działało to również dla sudo-H ll.
uav
3

Aliasy są specyficzne dla użytkownika - musisz je zdefiniować /root/.bashrc

Ragnar123
źródło
3
Są już w
katalogu /root/.bashrc,
1
Ta odpowiedź byłaby tylko poprawne dla sytuacji, gdy używasz skorupę się jako root, jak z sudo -slub sudo -i(i tylko jeśli prowadzonym przez siebie, aby uzyskać powłokę roota, nie z sudo -s command...lub sudo -i command...formach) lub sudo bashlub sudo sulub w sytuacji, gdy włączyłem logowanie roota i mam w ten sposób powłokę roota. Gdy użytkownik inny niż root uruchamia się sudo command...z własnej powłoki, rozszerzenie aliasu jest wykonywane przez jego własną powłokę inną niż root. sudosam nie rozwija aliasów, więc w przypadku sytuacji opisanej w pytaniu odpowiedź jest nieprawidłowa.
Eliah Kagan,
3

Odpowiedź @Alvins jest najkrótsza. Bez wątpienia! :-)

Jednak myślałem roztworu wiersza poleceń do wykonania polecenia sudo aliasem w których nie ma potrzeby, aby ponownie zdefiniować sudoza pomocą aliaspolecenia.

Oto moja propozycja dla tych, których może zainteresować:

Rozwiązanie

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

Przykład

W przypadku llpolecenia

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

Wyjaśnienie

gdy masz alias (taki jak :), llpolecenie type -azwraca aliasowane wyrażenie:

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

z greptobą wybierz tekst między akcentem „i apostrofem” w tym przypadkuls -l

I xargswykonuje zaznaczony tekst ls -ljako parametr sudo.

Tak, trochę dłużej, ale całkowicie czysto ;-) Nie ma potrzeby redefiniowania sudojako aliasu.

Lov.by.Jezus
źródło
3
Może być prostsze, jeśli użyłeś aliaswbudowanego, ponieważ jego wyjście jest czystsze. alias llwyjścia alias ll='ls -ahlF'.
muru
Oto wersja zawierające sugestię @ muru za: alias ll | sed "s/.*'\(.*\)'.*/\1/g" | xargs sudo.
ACK_stoverflow
Myślę, że celem pierwotnego pytania było uratowanie pracy, ponieważ nie musiałem sudo -inajpierw uruchamiać polecenia aliasu, ale robił to od razu. Posiadanie tak złożonego polecenia pokona to. Możesz zrobić to pierwsze i być znacznie szybszym.
Evi1M4chine
1

Mam inne fajne rozwiązanie, które dodaje trochę zaufania:

Użyj zakończenia bash, aby automatycznie zamieniać słowa sudoz ich aliasami po naciśnięciu klawisza tab.

Zapisz to jako /etc/bash_completion.d/sudo-alias.bashcompi powinno być automatycznie ładowane podczas interaktywnego uruchamiania powłoki:

_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

Następnie zaloguj się do nowego terminala i powinieneś iść.

Evi1M4chine
źródło
Istnieje sposób na uzyskanie listy aliasów, szczególnie przeznaczonych do uzupełnienia:compgen -a
muru,
@muru: Dzięki, ale w tym przypadku potrzebuję wartości, a nie kluczy. W związku z tym wprowadzony alias zostanie zastąpiony. Wpisujesz alias (jak w sudo ll), naciskasz [TAB ↹], a skrypt znajduje się llna liście przypisań aliasów, wycina to, do czego jest przypisany, i wstawia to. (Więc dostaniesz np sudo ls -lahvF --color=auto --time-style=long-iso.)
Evi1M4chine
0

Mam inne rozwiązanie, w którym nie trzeba dodawać sudojako aliasu. Korzystam z Linux Mint 17.3, ale powinien być podobny do Ubuntu.

Gdy jesteś rootem, .profilejest on uruchamiany z jego katalogu domowego. Jeśli nie wiesz, jaki jest katalog domowy w katalogu głównym, możesz to sprawdzić za pomocą:

sudo su
echo $HOME

Jak widać, domem rootjest /root/. Sprawdź jego zawartość:

cd $HOME
ls -al

Powinien być .profileplik. Otwórz plik i dodaj następujące wiersze:

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

Zasadniczo skrypt bash sprawdza, czy istnieje plik o nazwie .bash_aliases. Jeśli pliki są obecne, wykonuje plik.

Zapisz .profileplik i utwórz swoje aliasy w .bash_aliases. Jeśli masz już gotowy plik aliasów, skopiuj go do tej lokalizacji

Uruchom ponownie terminal i gotowe!

Karthik Ramakrishnan
źródło
0

Najlepiej głosowana odpowiedź jest świetna. Jednak jeśli wpiszesz sudo -ii #przejdziesz na sudo ( ), nie będziesz mieć aliasów, których lubisz używać.

Aby wykorzystać aliasy (i wszystko inne) w #wierszu polecenia, użyj:

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

Gdzie „$ PWD” jest automatycznie rozwijane do „/ home / YOUR_USER_NAME”

WinEunuuchs2Unix
źródło
0

@ WinEunuuchs2Unix: $PWDrozwija się do „obecnego katalogu roboczego”. Myślę, że chcesz $HOME.

Ponadto w większości sytuacji prawdopodobnie najlepiej jest mieć osobny główny plik .bashrc. W rzeczywistości uczynię go prawdziwym plikiem /root, miękkim linkiem do niego w katalogu domowym użytkownika (np. .bashrc_root) I źródłowym z .bashrcpliku użytkownika . Jeśli w późniejszym czasie to uprzywilejowane konto użytkownika nie będzie już obecne, .bashrcplik główny jest nadal dostępny dla innych użytkowników.

Shaun Griffith
źródło