Jak uruchomić polecenie „sudo” w skrypcie?

84

Aby ręcznie wykonać poprawkę, muszę wpisać to polecenie

sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  

Tuż przed 09 jest miejsce:

sudo ./playback_delete_data_patch.sh [space] 09_delete_old_data_p.sql

Jak mogę uruchomić to w skrypcie?

Istnieje również kilka innych poleceń, ale to sprawia problemy.

użytkownik251948
źródło
2
Po prostu umieść to w skrypcie, w czym problem?
Lie Ryan
6
@LieRyan - sudo hasło - skrypt nie będzie w stanie uruchomić się w pełni, jeśli kogoś tam nie będzie.
Wilf
Mój system po prostu działa bez problemów. Ubuntu 16.04 w październiku 2017 r. Zepsułeś swoją sudoerskonfigurację. Nie ma sprawy. To po prostu wymaga naprawy.
SDsolar,
1
@SDsolar Twój system jest tym, który popsuł się; niewielką luką w zabezpieczeniach jest nie monitowanie o hasło (czyni użytkowników bardziej podatnymi na niektóre rodzaje ataków socjotechnicznych).
wizzwizz4

Odpowiedzi:

107

Rzadko warto mieć sudowewnętrzne skrypty. Zamiast tego usuń sudoskrypt ze skryptu i uruchom sam skrypt za pomocą sudo:

sudo myscript.sh

W ten sposób wszystkie polecenia w skrypcie będą uruchamiane z uprawnieniami administratora, a hasło trzeba podać tylko raz podczas uruchamiania skryptu. Jeśli potrzebujesz określonej komendy w skrypcie, aby uruchamiać się bez sudouprawnień, możesz uruchomić ją jako zwykły użytkownik za pomocą (dzięki Lie Ryan ):

sudo -u username command 

Spacja jest nieistotna, nie powinna na nic wpływać, zawsze jest spacja między poleceniem a jego argumentami.

terdon
źródło
30
w skrypcie mogą znajdować się polecenia, które nie potrzebują uprawnień roota, możesz tymczasowo usunąć uprawnienia roota dla tych poleceń, używając sudo -u nazwa użytkownika
Lie Ryan
48
Wiele skryptów, które piszę, umożliwia interakcję użytkownika i / lub sprawdzanie błędów. Następnie jedno polecenie na końcu - coś w rodzaju rsync - musi zostać uruchomione jako root. Dlaczego miałbym chcieć sprawić, aby całość działała na wyższym poziomie i pozostawiłam otwartą na wiele wierszy kodu, które mogą zawierać poważne błędy lub luki w zabezpieczeniach dostępu do katalogu głównego - szczególnie podczas debugowania - gdy tylko jedno lub kilka poleceń wymaga takiego dostępu?
Joe
2
@Joe wystarczy. Zmieniono „nigdy nie dobry pomysł” na „rzadko”.
terdon
10
@Joe ma tutaj naprawdę dobry punkt. Również, gdy ktoś mówi , że tego nie rób , byłoby miło wiedzieć dokładnie, dlaczego tak jest, a przynajmniej w jakim kontekście nie powinienem tego robić i dlaczego
arainone
10
@terdon Nie słuchasz. Wiem, że jeśli uruchomisz skrypt jako root , nigdy nie poprosi cię o sudo. Porównuję to z tym, że nie uruchamiam skryptu jako root i zamiast tego umieszczam sudow skrypcie jawne wywołania, ponieważ podniesienie całego skryptu do roota może być okropnym pomysłem, jeśli istnieje tylko kilka wąskich działań, które wymagają rootowania. W tym kontekście odpowiadałem konkretnie na twój komentarz: „W dużej mierze, ponieważ oznacza to, że nie możesz uruchomić skryptu automatycznie, ponieważ będziesz musiał wprowadzić hasło za każdym razem, gdy zostaniesz o to poproszony”.
BeeOnRope
41

Możesz ewentualnie zmodyfikować sudoersplik.

Uruchom sudo visudo.

Dodaj wpis dla swojej nazwy użytkownika i skryptu, który chcesz uruchomić bez pytania o hasło.

username ALL=(ALL) NOPASSWD: /path/to/script
Klaus-Dieter Warzecha
źródło
2
Nie działało dla mnie, ale dziękuję, dobrze wiedzieć, że to istnieje. Być może źle zrozumiałem składnię.
Chris K
5
Nie jestem pewien, czy ktoś o tym wspomniał, ale po zakończeniu edycji musisz zakończyć wszystkie sesje logowania tego użytkownika sudoers.
escape-llc,
1
Aby to wyjaśnić, nie jest to skrypt, który zawiera wiersz „sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql”, który powinien zostać określony w pliku sudoers, ale skrypt play_delete_data_patch.sh lub dowolne inne polecenie, które użytkownik chce i / lub ich skrypty umożliwiające uruchomienie sudo bez podawania hasła.
MttJocy
19

Możesz spróbować czegoś takiego:

echo "PASSWORD" | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

To nie jest najbezpieczniejsza rzecz, ponieważ piszesz hasło sudoer zwykłym tekstem. Aby było trochę bardziej bezpieczne, możesz utworzyć zmienną i wczytać hasło sudo do zmiennej, a następnie możesz wykonać polecenie jako:

echo $PASSWORD | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

Ponadto, jeśli nie przeszkadza ci wykonywanie wszystkich poleceń jako root, możesz po prostu uruchomić skrypt za pomocą sudo, jak wcześniej sugerowano.

sudo ./myscript
Jibbers
źródło
read -s PASSWORD
Bezpieczne wczytywanie
10

Ta odpowiedź jest podobna do odpowiedzi Terdona . Sugerowałbym również uruchomienie skryptu głównego, sudoaby skrypt mógł działać bez konieczności podawania hasła użytkownika podczas jego wykonywania.

Jednak w przypadku, gdy chcesz upuścić uprawnienia administratora do niektórych poleceń i uruchomić je jako rzeczywisty użytkownik, który wywołał polecenie sudo, możesz sprawdzić, czy $SUDO_USERzmienna pozwala ustalić oryginalnego użytkownika.

Oto przykładowy skrypt, w jaki sposób możesz to osiągnąć:

#!/bin/bash

# ref: https://askubuntu.com/a/30157/8698
if ! [ $(id -u) = 0 ]; then
   echo "The script need to be run as root." >&2
   exit 1
fi

if [ $SUDO_USER ]; then
    real_user=$SUDO_USER
else
    real_user=$(whoami)
fi

# Commands that you don't want running as root would be invoked
# with: sudo -u $real_user
# So they will be run as the user who invoked the sudo command
# Keep in mind if the user is using a root shell (they're logged in as root),
# then $real_user is actually root
# sudo -u $real_user non-root-command

# Commands that need to be ran with root would be invoked without sudo
# root-command
Dan
źródło
4

Jest o wiele prostszy sposób na zrobienie tego. Jeśli chodzi o przenośność, jest to moja implementacja, ale możesz ją dowolnie modyfikować w zależności od potrzeb.

Wprowadź swoje hasło sudo jako parametr podczas uruchamiania skryptu, przechwyć je i powtórz za pomocą każdej komendy, która poprosi o podanie hasła sudo.

#!/bin/bash

PW=$1
echo $PW | ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  
./command_wo_sudo.sh <param>
echo $PW | ./other_command_requires_sudo.sh <param>

Możesz dodać monit i przechwycić po uruchomieniu skryptu w następujący sposób:

echo "enter the sudo password, please"
read PW

Ale jeśli ktoś inny monitoruje to, co działa w węźle; ma dostęp do utworzonych przez niego dzienników; lub po prostu losowo przegląda twój test, kiedy może to zagrozić bezpieczeństwu.

Działa to również z uruchomionymi poleceniami / skryptami, które wymagają tak, aby kontynuować:

echo $PW | yes | ./install.sh

Echo jest odpowiedzią na monit, więc możesz użyć tam wszystkiego, czego potrzebujesz, jeśli uruchamiasz inne skrypty z monitami o postęp, w kolejności sekwencyjnej. Upewnij się jednak, że znasz tę kolejność, ponieważ mogą się zdarzyć złe rzeczy.

csworenx
źródło
To o wiele bardziej eleganckie i proste, cieszę się, że przewinąłem do samego końca! EDYCJA: czekaj, to doda hasło do mojej historii terminala
Job
1
Jak poprosić o nazwę użytkownika / hasło za pomocą read: ryanstutorials.net/bash-scripting-tutorial/bash-input.php To powinno uniknąć tego problemu
Job
3
#!/bin/bash
# this declares that current user is a sudoer
sudo tee /etc/sudoers.d/$USER <<END
END

# write the content of your script here
sudo npm install hexo-cli -g
mkdir Untitled
sudo apt-get install python

# then to remove the sudo access from the current user
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k
Sanyam Jain
źródło
0

Możesz spróbować dodać użytkownika uruchamiającego skrypt do pliku sudoers:

#give permissions to the file
sudo chmod 700 /etc/sudoers.d/useradm

sudo visudo /etc/sudoers.d/useradm

#add the following text, changing "user" but your desired user
user ALL=(ALL)NOPASSWD:ALL

#return the right permissions to the file
sudo chmod 440 /etc/sudoers.d/useradm
evinhas
źródło
Ogólnie jest to zła metoda. Jeśli zamierzasz dodać reguły sudo NOPASSWD, szczególnie w przypadku kont, które uruchamiają automatyzację, powinieneś ograniczyć je do dokładnie uruchomionej komendy (a nie WSZYSTKICH)
Christopher Hunter