Dlaczego sudo ignoruje aliasy?

22

Używam Ubuntu 10.04 i używam upstartdo zarządzania demonem. Moja aplikacja korporacyjna jest uruchamiana jako demon i musi być uruchamiana jako root z powodu różnych uprawnień. Na przykład:

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

Chciałbym wprowadzić aliasskrót do tych poleceń jako coś w stylu:

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

i uruchom go jak startappi to działa, ale wolałbym nie mieć sudo w aliasie.

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

nie działa po uruchomieniu sudo startapp, powrót sudo: startapp: command not found.

Jednak gdy dodałem alias:

alias sudo='sudo '

sudo startapp teraz działa, ale wciąż jestem ciekawy, dlaczego sudo ignoruje aliasy.

amfibia
źródło
Czy twój bieg source ~/.bashrc? To aktualizuje plik .bashrc i udostępnia nowe aliasy?
manu
@manu Tak, zrobiłem
amfibia
1
serverfault.com/questions/61321/how-to-pass-alias-through-sudo
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Odpowiedzi:

35

Widzę stąd poniższe informacje .

Podczas korzystania z sudo użyj rozszerzenia aliasu (w przeciwnym razie sudo ignoruje twoje aliasy)

alias sudo='sudo '

Wyjaśniono tutaj powód, dla którego to nie działa .

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

Ramesh
źródło
6

Aliasy i funkcje są zdefiniowane w powłoce. Sudo to program zewnętrzny. Zatem sudo nie widzi aliasów, funkcji ani wbudowanych powłok, tylko polecenia zewnętrzne.

Aliasy mają być alternatywnymi nazwami poleceń, więc powłoki rozszerzają je tylko w pozycji poleceń, a nie wtedy, gdy są argumentami poleceń. Zsh obsługuje globalne aliasy, które są rozwijane w dowolnym miejscu wiersza poleceń, i najlepiej używać oszczędnie, ponieważ istnieje ryzyko ich przypadkowego rozwinięcia nawet w kontekstach, w których alias nie ma sensu.

Można powiedzieć sudo wywołać powłokę: sudo sh -c '…shell command here…'. Zwykłe aliasy nie będą jednak dostępne w tym poleceniu powłoki, ponieważ zwykle są przechowywane w pliku takim jak ~/.bashrclub, ~/.zshrcktóry jest odczytywany tylko przez interaktywne powłoki.

alias sudo='sudo ', jak zaproponował Ramesh , powoduje, że powłoka rozwija później aliasy sudo.

Gilles „SO- przestań być zły”
źródło
1
Czy alias sudo='sudo 'działa również dla ZSH?
CMCDragonkai
2
@CMCDragonkai Tak
Gilles „SO- przestań być zły”
1

Rozwiązanie dla użytkowników Zsh

Zarówno w bash, jak i zsh zakończenie aliasu spacją spowoduje, że powłoka alias rozszerzy następne słowo. Pozwala to na rozwinięcie aliasu w następujący sposóbmyalias

alias 'sudo=sudo '
sudo myalias

Niestety rozpada się, gdy w aliasie znajduje się więcej niż jedno słowo (np sudo -u someone. Można jednak użyć funkcji „globalne aliasy” zsh do ręcznego rozwijania aliasów w dowolnym miejscu polecenia.

alias -g '$= '

Tworzy to globalny alias o nazwie $(możesz użyć dowolnego słowa), który kończy się spacją. Powoduje to, że zsh rozwija następne słowo jako zwykły alias polecenia. Ponieważ alias rozwija się do białych znaków, nie będzie traktowany jako argument. Umożliwia to działanie następujących elementów.

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

Możesz nawet użyć $wiele razy w jednym wierszu poleceń, jeśli masz skomplikowane zagnieżdżanie poleceń. Znalazłem to na tyle przydatne, że ma stałe miejsce w moim Zshrc, jednak alias jest wystarczająco prosty, aby określić, kiedy trzeba go użyć.

Kevin Cox
źródło
0

Podałem tutaj alternatywną odpowiedź bez redefiniowania sudoza pomocą aliasu.

W twoim przypadku byłoby to:

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

Wszystko w jednym wierszu, bez dodatkowych powłok, bez redefiniowania aliasów. ;-)

Lov.by.Jezus
źródło
Och, poczekaj chwilę - rozumiem - używasz xargsdo rozebrania cytatów, a grep do rozebrania wiodących =. Trochę sprytne, ale prawdopodobnie niepotrzebne. eval "sudo $(alias aliasname | cut -d= -f2-)"jest prawdopodobnie lepszy - xargsnie zawsze będzie poprawnie obsługiwał cytatów i może być ich więcej niż jeden =.
mikeserv
@mikeserv Przykro mi, że tego nie dostałeś ;-) xargsnie usuwaj cytatów. To grep bierze rozstrzygnięte polecenie między cudzysłowami. Wiesz, type -a alias_namezwraca coś takiego alias_name is aliased to command_within_quotes. Nawiasem mówiąc, wypróbowałem twoje polecenie i nie type -a
działałem
Wiem co typerobi bash. Rozumiesz jednak, że cytaty są podwojone, prawda? Czy próbowałeś tego z aliasem zawierającym pojedyncze cytaty? W każdym razie, masz rację o moje rzeczy nie działa - trzeba albo eval "sudo sh -c "$(...albo eval "'sudo $(alias alias_name| cut -d\' -f2-)". Chodzi o to, że aliassą to w zasadzie wstępnie skonfigurowane evals - aliasnarzędzie jest wyspecyfikowane, aby wyświetlało zawartość, aby można ją było bezpiecznie ponownie wprowadzić do powłoki. Myślę, że twoja xargsimplementacja jest wtedy spłaszczona do białych znaków? Bądź z tym ostrożny, dobrze?
mikeserv