Jak mogę uzyskać polecenia sudo do korzystania z ustawień w /root/.bashrc

9

Dostosowałem .bashrcza pomocą szeregu aliasów, lla konkretnie iexport LS_OPTIONS='--color=auto'

Niestety nie działa to w połączeniu z sudo, więc również zmodyfikowałem /root/.bashrc, ale wydaje się, że to nie miało znaczenia.

sudo envpokazy HOME=/rootiSHELL=/bin/bash

Jak mogę uzyskać sudopolecenia do używania ustawień /root/.bashrc?

Rozumiem, że dzieje się tak tylko wtedy, gdy bashjest wykonywany interaktywnie, dlatego jestem otwarty na wszelkie inne sugestie dotyczące sposobu dostosowania.

Milliways
źródło
@ Daniel-Gelling - Zawsze czułem, że to Q jest problemem XY - meta.stackexchange.com/questions/66377/what-is-the-xy-problem . Tytuł sugeruje, że chcą czegoś poza, /root/.bashrcale tak naprawdę to, o co chodzi w Q, to aliasy z tego pliku - w tym przypadku nie jest to możliwe - unix.stackexchange.com/questions/1496/… .
slm
@slm co jestem po jest dodanie metody bashrc - jak robiłem w moim osobistym pliku .bashrc, jak plik .bashrc dla korzenia do „Wyłącz” z -ropcją crontab: crontab () { [[ $@ =~ -[iel]*r ]] && echo '"r" not allowed' || command crontab "$@" ;}. Działa to, gdy jestem zalogowany jako jeden z użytkowników, jednak po uruchomieniu sudo crontab -rnadal działa.
Daniel Gelling
@DanielGelling - sprawdź, czy moja odpowiedź działa w Twoim przypadku.
slm

Odpowiedzi:

6

sudouruchamia plik wykonywalny, a nie polecenie powłoki. Więc nie wie o aliasach. Jeśli uruchomisz sudo ls, sudo /bin/lsto znaczy, że nie używa żadnego lsaliasu, który możesz mieć.

Możesz spowodować sudo lsrozszerzenie aliasu, umieszczając w swoim .bashrc:

alias sudo='sudo '

Zwróć uwagę na spację końcową - to każe powłoce kontynuować ekspansję aliasu ze słowem, które następuje po sudo. Uwaga: rozszerzanie aliasów po sudo nie zawsze jest dobrym pomysłem, zależy to od rodzaju aliasów.

Ponadto sudo usuwa większość zmiennych ze środowiska. Nie wpłynie to na alias alias ls='ls $LS_OPTIONS', ponieważ jest to zmienna powłoki używana przez powłokę podczas rozwijania polecenia (i eksportowanie jej z .bashrcnie służy żadnemu celowi). Wpłynęłoby to jednak na zmienne używane przez polecenie, takie jak LS_COLORS. Możesz skonfigurować sudo, aby zachować pewne zmienne środowiskowe, edytując jego konfigurację: uruchom visudoi dodaj linię

Defaults env_keep += "LS_COLORS"

Dzięki tym ustawieniom sudo llotrzymasz kolory, do których jesteś przyzwyczajony.

Alternatywnie możesz uruchomić powłokę root za pomocą sudo -s. Ta powłoka załaduje swój plik konfiguracyjny ( ~/.bashrcdla bash). W zależności od konfiguracji sudo może to być HOMEustawione na katalog domowy lub zmienić na /root. Możesz wymusić ustawienie katalogu domowego na root sudo -Hs; i odwrotnie, aby zachować oryginalny katalog domowy, uruchom sudo env HOME="$HOME" bash.

Gilles „SO- przestań być zły”
źródło
3

Dziękuję tym, którzy odpowiedzieli, którzy skłonili mnie do man sudobardziej uważnego przeczytania .

sudo -s Jeśli nie podano żadnego polecenia, wykonywana jest powłoka interaktywna.

Ta interaktywna powłoka używa, /root/.bashrca zatem zawiera moje dostosowania.

Wymaga osobnego wprowadzenia polecenia, ale jest to w porządku.

Milliways
źródło
2

tło

Zawsze czułem, że to pytanie jest problemem XY . Tytuł sugeruje, że chcą czegoś poza, /root/.bashrcale tak naprawdę to, o co chodzi, to aliasy z tego pliku - powszechnie uważa się, że nie jest to możliwe - Dlaczego mój skrypt Bash nie rozpoznaje aliasów? .

Zasadniczo jest to z założenia, że ​​twoje aliasy nie zostaną rozpoznane sudow innych miejscach, ponieważ nie są przenośne, i to też jest moja opinia na ich temat.

Wszystko, co znajduje się w środowisku użytkownika, nie powinno być uwzględniane przez skrypty i żadne oprogramowanie, które może działać na danym urządzeniu. Ale zdaję sobie sprawę, że istnieją scenariusze, w których na koncie danego użytkownika mogą znajdować się aliasy, $HOME/.bashrcktóre inni mogą chcieć wykorzystać w interaktywnych scenariuszach.

W tym celu możesz po prostu powiedzieć interpreterowi Bash, aby rozwinął wszelkie aliasy, które znajdzie podczas procesu logowania, poza normalnymi zachowaniami powłoki, na które natrafisz podczas używania sudo.

Przykład

Ustawiać

Aby to skonfigurować, dodałem następujące aliasy, zmienne środowiskowe i funkcje do mojego użytkownika root /root/.bashrci /root/.bash_profileplików.

$ grep smurf ~/.bashrc
alias brc_smurf='echo "ran alias from /root/.bashrc"'
export brc_smurf_env='var from /root/.bashrc'
bpf_smurf_func() { echo 'ran func from /root/.bash_profile'; }

$ grep smurf ~/.bash_profile
alias bpf_smurf='echo "ran alias from /root/.bash_profile"'
export bpf_smurf_env='var from /root/.bash_profile'
brc_smurf_func() { echo 'ran func from /root/.bashrc'; }

Bez robienia czegokolwiek z tych prac (bez niespodzianek):

$ sudo brc_smurf
sudo: brc_smurf: command not found

$ sudo bpf_smurf
sudo: bpf_smurf: command not found

Widzimy, że aliaspolecenie nie wyświetla aliasów po uruchomieniu sudo:

$ sudo alias
$

Takie zachowanie jest wskazówką, że nie należy oczekiwać, że aliasy będą dostępne. Ale kontynuujemy ...

Krok # 1 - widoczne aliasy

Jeśli uruchomimy bash -ci, możemy skłonić Basha do przeczytania przynajmniej $HOME/.bashrc:

$ sudo bash -ci 'alias' | grep smurf
alias brc_smurf='echo "ran alias from /root/.bashrc"'

Fajnie, więc może możemy to uruchomić?

$ sudo bash -ci 'alias; brc_smurf'
bash: alias; brc_smurf: No such file or directory

Krok 2 - shopt -s expand_aliases

Nie. Znowu jest to zgodne z projektem, robimy coś, czego nie powinniśmy robić, więc istnieje szereg „zabezpieczeń”, które musimy wyłączyć. drugim „bezpieczeństwem” jest Bash.

$ sudo bash -ci 'shopt -s expand_aliases; alias; brc_smurf'
alias brc_smurf='echo "ran alias from /root/.bashrc"'
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
ran alias from /root/.bashrc

Tutaj widzimy naszą wiadomość, z /root/.bashrcpowodzeniem wykonaliśmy alias użytkownika root brc_smurf.

Krok # 3 - co z warnikami env?

Jeśli używasz metody pokazanej powyżej, powinny one również działać.

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env'
ran alias from /root/.bashrc
var from /root/.bashrc

Krok # 4 - co z funkcjami?

Działa to również zgodnie z oczekiwaniami:

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env;brc_smurf_func'
ran alias from /root/.bashrc
var from /root/.bashrc
ran func from /root/.bashrc

TLDR;

Możesz to zrobić, aby uzyskać dostęp do zmiennych środowiskowych + aliasów z /root/.bashrc:

$ sudo bash -ci 'shopt -s expand_aliases; <cmds>'

Wynos

Ta metoda włącza zawartość /root/.bashrc, nie pobiera zawartości /root/.bash_profile.

Bibliografia

slm
źródło
Tak, choć między nimi są niewielkie różnice, nie wchodźmy tutaj w szczegóły ;-). W każdym razie, czy mógłbyś mi pomóc w sytuacji opisanej w komentarzach do pytania: używanie funkcji w .bashrcsudo; konkretnie usuwając -ropcję z crontab?
Daniel Gelling
Okej, ale to oznaczałoby, że musiałbym biec: sudo bash -ci 'alias; shopt -s expand_aliases; echo $brc_smurf_env'zamiast zwykłego sudo echo $brc_smurf_env?
Daniel Gelling
Możesz usunąć alias, to było po prostu ich pokazać, musisz to zrobićsudo bash -ci 'shopt -s expand_aliases; <cmds>'
slm
To byłoby dużo pisania tylko po to, by edytować mój crontab dla roota. Pozwól, że utworzę dla niego alias :-P
Daniel Gelling
@DanielGelling - tak, witamy w całej zabawie w trzewiach.
slm
0

W pliku / etc / sudoers znajduje się kilka ustawień lub konfiguracja środowiska, w którym uruchamiane są polecenia sudo (np. Upewnij się, że PATH ma tylko zaufane lokalizacje), ale w zależności od tego, co chcesz z tego wydostać możesz nie być w stanie zrobić tego, czego szukasz, jeśli wymaga to uruchomienia rzeczywistych poleceń w powłoce w celu skonfigurowania środowiska. Sudoing specjalnie nie daje powłoki logowania roota, więc nie utworzy dla ciebie zwykłego profilu.

hvindin
źródło
0

Powiedzmy, że edytujemy /root/.bashrc, aby być:

$ sudo su -
Password: ******
# cat ~/.bashrc

echo "root bashrc file was read"
PATH=~/bin:$PATH
echo "$PATH"
export USERVAR=set
echo "$USERVAR"

umask 022
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -lA'

Pozwala się wylogować i zalogować ponownie, aby bash odczytał plik:

# exit
$ sudo su -
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@here:~# alias l
alias l='ls $LS_OPTIONS -lA'
root@here:~# 

Jak widać plik został odczytany, zmieniono ŚCIEŻKĘ i ustawiono aliasy. Wszystko działa tak, jak prosisz.

Jednak sudo nadal nie będzie działać zgodnie z oczekiwaniami.

root@here:~# exit
$ sudo env | grep USERVAR              # no output 
$ sudo env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

ŚCIEŻKA się nie zmieniła. Mogą istnieć sposoby zmiany ścieżki w sudoers, ale zdecydowanie zalecamy unikanie tego. Poza tym aliasy, funkcje i niektóre inne zmiany nadal nie zostaną zastosowane przez zmianę tylko ŚCIEŻKI. Plik musi zostać pobrany. Wykonanie tego dla każdego skryptu lub polecenia spowoduje, że komputer wykona więcej pracy bez żadnych rzeczywistych korzyści. Skrypty nie używają aliasów (nie ma praktycznego zastosowania w skryptach).

Po prostu zaloguj się, .bashrcplik zostanie automatycznie załadowany i zacznie działać.

Możesz rozpocząć bash w następujący sposób:

$ sudo bash
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@mail:/home/isaac/me/temp/clocks-master#

Ale jak widać powyżej, pwd (katalog roboczy) nie zmienił się, a jeśli przyjrzysz się nieco więcej, niektóre inne ustawienia również się nie zmieniły. Dlatego poprawnym poleceniem jest użycie:

$ sudo su -

Jeśli to polecenie jest zbyt długie, aby je wpisać, utwórz alias lub funkcję użytkownika (nie root), w której będzie ono używane, coś w stylu:

$ alias mysu='sudo su -'
$ mysu
# 
Izaak
źródło
0

TL; DR: Możesz użyć sudo -ido uruchomienia funkcji zdefiniowanej /root/.bashrc(ale nie aliasu), a także mieć dostęp do zmiennych eksportowanych z tego pliku:

Argumenty polecenia sudo -i 

Aliasy tam jednak nie działają, ale możesz łatwo przekonwertować je na funkcje, jeśli chcesz je udostępnić sudo -i.

Czytaj dalej, aby uzyskać pełną analizę i więcej szczegółów.


Jest tu kilka problemów, niektóre z tego, jak działa sudo, a niektóre z samego bash ...

Domyślnie sudoszuka tylko poleceń i omija powłokę, więc po prostu uruchomienie sudo llbędzie działać tylko wtedy, gdy llw jednym z katalogów znajduje się plik wykonywalny $PATH. Tak więc, aby użyć aliasów (lub funkcji), musisz upewnić się, że powłoka jest wywoływana jako część procesu.

Jednym ze sposobów byłoby uruchomienie czegoś podobnego sudo shlub sudo bashchociaż nowoczesny sudo(testuję to na sudo 1.8.19p1) ma opcje -si -ido tego celu.

Tak więc jedna próba byłaby czymś podobnym sudo -s ll(co jest równoważne z sudo bash -c 'll'założeniem, że masz $SHELLBash, co wydaje się być oparte na tym rcfile, o którym wspomniałeś). Ale to też nie działa, ponieważ uruchamia powłokę w sposób nieinteraktywny, tryb bez logowania, który nie odczytuje żadnych plików startowych. Zasadniczo jest tak samo, jakbyś napisał skrypt powłoki i użył go #!/bin/bashdo uruchomienia. Aliasy (i funkcje), które masz w swoim ~/.bashrc, nie będą dostępne z tego skryptu ...

Następna jest -iopcja, która tworzy powłokę logowania. To bardziej obiecujące, ponieważ będzie czytać swoje pliki startowe! A jednak sudo -i ll(odpowiednik sudo bash -l -c 'll') nadal nie będzie działać. Więc jak to możliwe, biorąc pod uwagę, że nie czytać definicji llaliasu?

Cóż, kolejne wyjaśnienie tutaj jest takie, że domyślnie bash nie będzie rozwijał aliasów, z wyjątkiem sytuacji, gdy powłoka jest interaktywna ... Ta powłoka uruchomiona przez sudo -i(lub bash -l) jest powłoką logowania , ale nadal nie jest interaktywna.

Następnym krokiem jest uzyskanie interaktywnej powłoki, która następnie działa :

sudo bash -i -c 'll'

( Oczywiście zarówno logowanie, jak i interaktywne również są w porządku bash -l -i -c ...).

Inną alternatywą jest dalsze używanie powłoki logowania (nieinteraktywnej), ale wyraźne poproszenie jej o rozwinięcie aliasów, aby działało to również:

sudo bash -l -O expand_aliases -c 'll'

(Przypadek, w którym bash był interaktywny, nie wymagał powłoki logowania , ponieważ to wystarczy, aby odczytać pliki inicjujące, ale ten musi -lje przeczytać).

Są to dość długie wiersze poleceń ... Wymagają również zacytowania całego polecenia powłoki, więc jeśli wywołujesz alias z argumentami, musisz przekształcić to wszystko w ciąg znaków ... Więc to jest rodzaj niezdarny w użyciu ...

Zauważ, że wcześniej mówiłem o aliasach i funkcjach ... To było celowe, ponieważ funkcje są tutaj o wiele wygodniejsze. Nie potrzebujesz niczego specjalnego (takiego jak posiadanie interaktywnej powłoki lub ustawienie konkretnej opcji) do wykonywania funkcji w powłoce, o ile pozyskujesz ich definicję.

Więc jeśli zdefiniowałeś lljako funkcję zamiast aliasu, możesz użyć go bezpośrednio za pomocą -iskrótu sudo :

sudo -i ll

A jeśli masz dłuższą linię poleceń z argumentami, możesz przekazać je również tutaj:

sudo -i ll -C -R /etc

(Porównaj z sudo bash -i -c 'll -C -R /etc'.)

Funkcje są również znacznie bardziej elastyczne i zazwyczaj łatwiejsze w utrzymaniu ... Zazwyczaj alias można przekształcić w funkcję, jedynym zastrzeżeniem jest zawsze używanie "$@"tam, gdzie można oczekiwać dodatkowych argumentów (zwykle na końcu Alias.)

Na przykład ten alias:

alias ll='ls $LS_OPTIONS -l'

Można włączyć tę funkcję:

ll () {
    ls $LS_OPTIONS -l "$@"
}

W większości przypadków są one równoważne. Jak wspomniano wcześniej, funkcja powinna być dostępna bezpośrednio z sudo -i, więc jest to dodatkowy bonus.

Mam nadzieję, że ta odpowiedź i wyjaśnienie okażą się pomocne!

filbranden
źródło
DV - Nie wydaje mi się, żeby to poprawiało już sytuację, niż to, co już tu jest.
slm
1
@slm uważam, że moja odpowiedź jest dodanie czegoś, ponieważ żaden poprzedni odpowiedź wspomniano formularz sudo -i command arguments, aby móc uruchomić funkcje z /root/.bashrci są eksportowane zmienne dostępne. Ale widzę, że moja odpowiedź była może zbyt długa, a ta informacja była tam trochę zakopana ... Więc dodałem TL; DR, żeby to podsumować (wciąż zachowując techniczne szczegóły dochodzenia.) Proszę spojrzeć jeszcze raz.
filbranden