2012-04-19 9 views
52

Ich möchte ein Shell-Skript schreiben, um eine Reihe von Befehlen zu automatisieren. Das Problem ist, dass einige Befehle als Superuser ausgeführt werden müssen und einige Befehle NICHT als Superuser ausgeführt werden dürfen. Was ich habe, ist bisher getan etwas wie folgt aus:Wie schreibe ich ein Shell-Skript, das einige Befehle als Superuser und einige Befehle nicht als Superuser ausführt, ohne es zu babysitten?

#!/bin/bash 

command1 
sudo command2 
command3 
sudo command4 

Das Problem ist, bedeutet dies, jemand warten muss, bis command1 beendet ist, bevor sie nach einem Passwort gefragt werden, dann, wenn command3 lange genug dauert, werden sie dann muss warten bis command3 fertig ist. Es wäre schön, wenn die Person aufstehen und gehen könnte, dann eine Stunde später zurückkommen und fertig sein würde. Zum Beispiel hat das folgende Skript dieses Problem:

#!/bin/bash 

sleep 310 
sudo echo "Hi, I'm root" 
sleep 310 
sudo echo "I'm still root?" 

Wie kann ich es machen, so dass der Benutzer sein Passwort nur einmal eingeben, ganz am Anfang, und dann zu Fuß zu erreichen?

Update:

Danke für die Antworten. Ich laufe auf Mac OS X Lion und lief Skripts Stephen P und bekam unterschiedliche Ergebnisse: (Ich habe auch $ HOME)

[email protected] scratch$ ./test2.sh 
uid is 501 
user is pair 
username is 
home directory is /Users/pair 
[email protected]bbey scratch$ sudo ./test2.sh 
Password: 
uid is 0 
user is root 
username is root 
home directory is /Users/pair 

Antwort

42

Datei sutest

#!/bin/bash 
echo "uid is ${UID}" 
echo "user is ${USER}" 
echo "username is ${USERNAME}" 

laufen sie: `./sutest‘ gibt mir

uid is 500 
user is stephenp 
username is stephenp 

aber sudo: sudo ./sutest gibt

Sie behalten also den ursprünglichen Benutzernamen in $ USERNAME, wenn Sie als sudo ausgeführt werden.Dies führt zu einer Lösung ähnlich dem, was andere geschrieben:

#!/bin/bash 
sudo -u ${USERNAME} normal_command_1 
root_command_1 
root_command_2 
sudo -u ${USERNAME} normal_command_2 
# etc. 

Gerade sudo Ihr Skript an erster Stelle zu berufen, wird es einmal nach dem Passwort fragen.


Ursprünglich schrieb ich diese Antwort auf Linux, die mit OS X

OS X einige Unterschiede hat (Ich teste diese auf Mountain Lion 10.8.3) hat eine Umgebungsvariable SUDO_USERwenn 's running sudo, das anstelle von USERNAME oben verwendet werden kann, oder um plattformübergreifend zu sein, könnte das Skript prüfen, ob SUDO_USER gesetzt ist, und es verwenden, falls dies der Fall ist, oder USERNAME verwenden, falls dies gesetzt ist.

das ursprüngliche Skript für OS X ändern, wird es ...

#!/bin/bash 
sudo -u ${SUDO_USER} normal_command_1 
root_command_1 
root_command_2 
sudo -u ${SUDO_USER} normal_command_2 
# etc. 

Ein erster Stich zu machen, es Cross-Plattform sein könnte ...

#!/bin/bash 
# 
# set "THE_USER" to SUDO_USER if that's set, 
# else set it to USERNAME if THAT is set, 
# else set it to the string "unknown" 
# should probably then test to see if it's "unknown" 
# 
THE_USER=${SUDO_USER:-${USERNAME:-unknown}} 

sudo -u ${THE_USER} normal_command_1 
root_command_1 
root_command_2 
sudo -u ${THE_USER} normal_command_2 
# etc. 
+0

Sie können auch eine Schale machen Skript, das root gehört und das Bit "suid" gesetzt hat, aber das kann gefährlich sein, wenn Sie es nicht richtig machen. Jedes Mal, wenn Sie Shell-Skripte als root ausführen, sollten Sie in Erwägung ziehen, 'trap' zu verwenden, um Signale zu verarbeiten. http://www.shelldorado.com/goodcoding/tempfiles.html hat einige Beispiele. –

+0

Komisch, ich bekomme tatsächlich unterschiedliche Ergebnisse. Dies ist auf Mac OS X Lion: 'Paar @ Abtei Kratzer $/test2.sh'
' uid ist 501'
'Benutzer ist pair'
' username is '
' Home-Verzeichnis/Users/Paar. '
' Paar @ Abtei Grund auf neu $ sudo ./test2.sh '
' Passwort: '
' uid ist 0'
'Benutzer ist root'
' username is root'
'Home-Verzeichnis/Benutzer/Paar
'Paar @ Abtei Scratch $ Sudo -u Paar ./test2.sh'
'Uid ist 501'
'Benutzer
pair' ist' username is pair'
'Home-Verzeichnis/Users/pair'
speedarius

+0

Sorry für die Formatierung des obigen Kommentars; Ich aktualisiere den ursprünglichen Post jetzt. – speedarius

9

Sie sollten Ihre gesamte Skript als Superuser ausgeführt werden. Wenn Sie einen Befehl als Nicht-Superuser ausführen möchten, verwenden Sie Option „-u“ von sudo:

#!/bin/bash 

sudo -u username command1 
command2 
sudo -u username command3 
command4 

Wenn als root ausgeführt wird, wird sudo nicht nach einem Passwort fragen.

3

Wenn Sie diese verwenden, überprüfen man sudo auch:

#!/bin/bash 

sudo echo "Hi, I'm root" 

sudo -u nobody echo "I'm nobody" 

sudo -u 1000 touch /test_user 
3

Nun, Sie einige Optionen.

Sie könnten sudo so konfigurieren, dass Sie nicht nach einem Passwort fragen. Dies wird aufgrund der Sicherheitsrisiken nicht empfohlen.

Sie könnten ein expect-Skript schreiben, um das Passwort zu lesen und es bei Bedarf an sudo zu übergeben, aber das ist klobig und zerbrechlich.

Ich würde empfehlen, das Skript so zu gestalten, dass es als root ausgeführt wird und seine Berechtigungen löscht, wenn sie nicht benötigt werden. Lassen Sie es einfach sudo -u someotheruser command für die Befehle, die root nicht benötigen.

(Wenn sie speziell ausgeführt werden müssen, während der Benutzer das Skript aufruft, dann könnte das Skript die UID speichern und ein zweites Skript über sudo mit der ID als Argument aufrufen, damit es weiß, an wen es sich richtet.

)