Mam skrypt, który wykonuje wiele różnych czynności, z których większość nie wymaga żadnych specjalnych uprawnień. Jednak jedna konkretna sekcja, którą zawarłem w ramach funkcji, wymaga uprawnień roota.
Nie chcę wymagać, aby cały skrypt działał jako root i chcę móc wywoływać tę funkcję z uprawnieniami roota z poziomu skryptu. Żądanie hasła w razie potrzeby nie stanowi problemu, ponieważ i tak jest w większości interaktywne. Jednak gdy próbuję użyć sudo functionx
, otrzymuję:
sudo: functionx: command not found
Tak jak się spodziewałem, export
nie miało to znaczenia. Chciałbym być w stanie wykonać funkcję bezpośrednio w skrypcie, zamiast rozbijać ją i wykonywać jako osobny skrypt z wielu powodów.
Czy jest jakiś sposób, aby uczynić moją funkcję „widoczną” dla sudo bez wypakowywania jej, znajdowania odpowiedniego katalogu, a następnie wykonywania go jako samodzielnego skryptu?
Ta funkcja dotyczy samej długości strony i zawiera wiele ciągów znaków, niektóre cudzysłowy i niektóre cudzysłowy. Zależy również od funkcji menu zdefiniowanej w innym miejscu w głównym skrypcie.
Spodziewałbym się tylko, że ktoś z sudo KAŻDY będzie mógł uruchomić tę funkcję, ponieważ jedną z rzeczy, które robi, jest zmiana hasła.
declare
je.Odpowiedzi:
Przyznaję, że nie ma prostego, intuicyjnego sposobu, aby to zrobić, a to jest trochę hackey. Ale możesz to zrobić w następujący sposób:
Lub prościej:
Mi to pasuje:
Zasadniczo
declare -f
zwróci zawartość funkcji, którą następnie przekażeszbash -c
inline.Jeśli chcesz wyeksportować wszystkie funkcje z zewnętrznego wystąpienia bash, zmień
FUNC=$(declare -f hello)
naFUNC=$(declare -f)
.Edytować
Aby odnieść się do komentarzy na temat cytowania, zobacz ten przykład:
źródło
echo "Hello!"
jest faktycznie takie samo jakecho Hello!
(tzn. Podwójne cudzysłowy nie mają znaczenia dla tego konkretnego polecenia echa). W wielu / większości innych przypadków podwójne cudzysłowy w funkcji prawdopodobnie powodują przerwaniebash -c
polecenia.bash -xc
raczej niż tylkobash -c
) i wygląda na to, żebash
jest wystarczająco inteligentny, aby cytować rzeczy w tej sytuacji, nawet w zakresie zastępowania podwójnych cudzysłowów pojedynczymi cudzysłowami i zmieniania'
na,'\''
jeśli to konieczne. Jestem pewien, że będą pewne przypadki, których nie będzie w stanie obsłużyć, ale na pewno działa to w co najmniej prostych i średnio skomplikowanych przypadkach - np. Tryfunction hello() { filename="this is a 'filename' with single quotes and spaces" ; echo "$filename" ; } ; FUNC=$(declare -f hello) ; bash -xc "$FUNC ; hello"
declare -f
drukuje definicji funkcji w sposób, który może być ponownie przetwarzane przez bash takbash -c "$(declare -f)"
robi działają prawidłowo (przy założeniu, że zewnętrzna powłoka jest atakujących). W opublikowanym przykładzie pokazano, że działa poprawnie - tam, gdzie zmieniono cudzysłowy, znajduje się w śladzie , ponieważ bash drukuje ślady w składni powłoki, np. Spróbujbash -xc 'echo "hello world"'
sudo yourFunction
nie można go znaleźć (w przeciwnym razie podczas rekursji„Problem” polega na tym, że
sudo
oczyszcza środowisko (z wyjątkiem kilku dozwolonych zmiennych) i ustawia niektóre zmienne na wstępnie zdefiniowane bezpieczne wartości w celu ochrony przed zagrożeniami bezpieczeństwa. innymi słowy, nie jest to tak naprawdę problemem. To funkcja.Na przykład, jeśli ustawiłeś
PATH="/path/to/myevildirectory:$PATH"
isudo
nie ustawiłeś PATH na wstępnie zdefiniowaną wartość, wówczas każdy skrypt, który nie określiłby pełnej ścieżki do WSZYSTKICH poleceń, które uruchamia (tj. Większość skryptów) szukałby/path/to/myevildirectory
przed jakimkolwiek innym katalogiem. Umieszczaj w nim polecenia takie jakls
lubgrep
inne popularne narzędzia, dzięki czemu możesz łatwo robić, co chcesz w systemie.Najłatwiejszym / najlepszym sposobem jest ponowne zapisanie funkcji jako skryptu i zapisanie jej gdzieś na ścieżce (lub określenie pełnej ścieżki do skryptu w
sudo
wierszu poleceń - co i tak musisz zrobić, chyba żesudo
skonfigurowano to tak, aby ci pozwalało aby uruchomić DOWOLNĄ komendę jako root) i uczynić ją wykonywalną za pomocąchmod +x /path/to/scriptname.sh
Przebudowywanie powłoki funkcję jako skrypt jest tak proste, jak to tylko oszczędność poleceń wewnątrz definicji funkcji w pliku (bez
function ...
,{
a}
wiersze).źródło
sudo -E
Unika także czyszczenia środowiska.W tym celu napisałem własną
Sudo
funkcję bash, która działa do wywoływania funkcji i aliasów:źródło
Możesz łączyć funkcje i aliasy
Przykład:
wtedy
sudo hello
działaźródło
Oto wariant odpowiedzi Willa . Wymaga dodatkowego
cat
procesu, ale oferuje komfort heredoc. W skrócie wygląda to tak:Jeśli chcesz więcej do myślenia, spróbuj tego:
Dane wyjściowe to:
Tutaj mamy
menu
funkcję odpowiadającą tej w pytaniu, która jest „zdefiniowana gdzie indziej w głównym skrypcie”. Jeśli „gdzie indziej” oznacza, że jego definicja została już odczytana na tym etapie, gdy wykonywana jest funkcja wymagającasudo
, sytuacja jest analogiczna. Ale może jeszcze nie został przeczytany. Może istnieć inna funkcja, która jeszcze uruchomi jej definicję. W takim przypadkudeclare -f menu
należy zastąpić coś bardziej zaawansowanego lub cały skrypt skorygowany w taki sposób, żemenu
funkcja jest już zadeklarowana.źródło
menu
funkcja zostałaby zadeklarowana przed tym punktem, ponieważf
jest wywoływana z menu.Zakładając, że twój skrypt jest (a) samowystarczalny lub (b) może pozyskiwać swoje komponenty na podstawie jego lokalizacji (zamiast zapamiętywania twojego katalogu domowego), możesz zrobić coś takiego:
$0
ścieżki do skryptu, używając tej wsudo
poleceniu, i przekaż opcję, którą skrypt sprawdzi, aby wywołać aktualizację hasła. Tak długo, jak polegasz na znalezieniu skryptu na ścieżce (zamiast po prostu uruchomić./myscript
), powinieneś otrzymać bezwzględną nazwę ścieżki$0
.sudo
uruchamia skrypt, ma dostęp do funkcji potrzebnych w skrypcie.uid
i zda sobie sprawę, że został uruchomiony jako użytkownik root , i zobaczy, że ma ustawioną opcję nakazującą mu aktualizację hasła, idź i zrób że.Skrypty mogą się powtarzać z różnych przyczyn: jednym z nich jest zmiana uprawnień.
źródło