Come posso eseguire un comando 'sudo' all'interno di uno script?


84

Per fare una patch manualmente devo digitare questo comando

sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  

C'è uno spazio poco prima del 09:

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

Come posso eseguirlo all'interno di uno script?

Ci sono anche molti altri comandi, ma questo sta dando problemi.


2
Basta inserirlo nella sceneggiatura, qual è il problema?
Lie Ryan,

6
@LieRyan - la sudo password - lo script non sarà in grado di funzionare completamente se qualcuno non è lì per inserirlo.
Wilf,

Il mio sistema li fa funzionare senza problemi. Ubuntu 16.04 nell'ottobre 2017. Hai incasinato la tua sudoersconfigurazione. Nessun grosso problema. Deve solo essere riparato.
SDsolar,

1
@SDsolar Il tuo sistema è quello che è incasinato; è una vulnerabilità di sicurezza minore a non richiedere la password (rende gli utenti più vulnerabili ad alcuni tipi di attacchi di social engineering).
wizzwizz4,

Risposte:


107

Raramente è una buona idea avere degli sudoscript interni. Invece, rimuovi lo sudodallo script ed esegui lo script stesso con sudo:

sudo myscript.sh

In questo modo, tutti i comandi all'interno dello script verranno eseguiti con i privilegi di root e sarà necessario fornire la password una sola volta all'avvio dello script. Se hai bisogno di un comando particolare all'interno dello script per essere eseguito senza sudoprivilegi, puoi eseguirlo come utente normale con (grazie a Lie Ryan ):

sudo -u username command 

Lo spazio è irrilevante, non dovrebbe interessare nulla, c'è sempre uno spazio tra un comando e i suoi argomenti.


30
potrebbero esserci dei comandi nello script che non necessitano del privilegio di root, puoi rilasciare temporaneamente il privilegio di root per quei comandi usando sudo -u username
Lie Ryan

48
Molti script che scrivo eseguono un'intera serie di interazioni dell'utente e / o controllo degli errori. Quindi un comando alla fine - qualcosa come rsync - deve essere eseguito come root. Perché dovrei voler rendere l'intera operazione elevata e lasciarmi aperta a molte righe di codice che potrebbero contenere gravi errori o vulnerabilità con accesso root - specialmente durante il debug - quando solo uno o pochi comandi richiedono tale accesso?
Joe,

2
@Joe abbastanza giusto. Modificato il "mai una buona idea" in "raramente".
terdon

10
@Joe ha davvero un buon punto qui. Inoltre, quando uno dice di non farlo , sarebbe bello sapere esattamente perché o almeno in quale contesto non dovrei farlo, e perché
arainone,

10
@terdon Non stai ascoltando. So che se esegui lo script come root non ti chiederà mai sudo. Lo sto confrontando con il non eseguire lo script come root e inserendo invece sudochiamate esplicite nello script, perché elevare l'intero script alla radice può essere una terribile idea se ci sono solo una manciata di azioni ristrette che hanno bisogno di root. In quel contesto stavo rispondendo in modo specifico al tuo commento: "In gran parte perché ciò significa che non puoi eseguire lo script automaticamente poiché dovrai inserire la password ogni volta che ti viene chiesto".
BeeOnRope

40

È possibile modificare il sudoersfile.

Corri sudo visudo.

Aggiungi una voce per il tuo nome utente e lo script che desideri eseguire senza che ti venga richiesta una password.

username ALL=(ALL) NOPASSWD: /path/to/script

2
Non ha funzionato per me, ma grazie, è bello sapere che esiste. Forse ho sbagliato la sintassi.
Chris K,

5
Non sei sicuro che qualcuno l'abbia menzionato, ma devi terminare tutte le sessioni di accesso di quell'utente dopo aver modificato il sudoersfile.
escape-llc,

1
Giusto per chiarire qui non è lo script che contiene la riga "sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql" che dovrebbe essere specificata nel file sudoers ma lo script playback_delete_data_patch.sh o qualunque altro comando tu voglia quell'utente e / o il loro script per poter eseguire sudo senza specificare una password.
MttJocy,

19

Potresti provare qualcosa del tipo:

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

Questa non è la cosa più sicura da fare poiché stai scrivendo una password sudoer in testo semplice. Per renderlo un po 'più sicuro puoi creare una variabile e leggere la password sudo nella variabile e quindi eseguire il comando come:

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

Inoltre, se non ti dispiace che tutti i tuoi comandi vengano eseguiti come root, puoi semplicemente eseguire lo script usando sudo, come precedentemente suggerito.

sudo ./myscript

Lettura sicura della password in variabile:read -s PASSWORD
Tobias Uhmann

10

Questa risposta è simile alla risposta di Terdon . Suggerirei anche di eseguire lo script principale con in sudomodo che lo script possa essere eseguito senza dover richiedere la password dell'utente durante la sua esecuzione.

Tuttavia, nel caso in cui si desideri rilasciare i privilegi di root su alcuni dei comandi ed eseguirli come l'utente effettivo che ha invocato il comando sudo, è possibile verificare la $SUDO_USERvariabile per capire l'utente originale.

Questo è uno script di esempio di come potresti riuscirci:

#!/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

4

In realtà esiste un modo molto più semplice per farlo. Per la portabilità, questa è la mia implementazione, ma sentiti libero di manipolarla per soddisfare le tue esigenze.

Inserisci la tua password sudo come parametro quando avvii lo script, acquisiscilo ed esegui l'eco con ogni comando che richiederà la password 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>

È possibile aggiungere un prompt e acquisire dopo che lo script è stato avviato in questo modo:

echo "enter the sudo password, please"
read PW

Ma se qualcun altro controlla ciò che viene eseguito sul nodo; ha accesso ai registri da esso creati; o sta semplicemente esaminando il tuo caso in modo casuale quando si esegue un test, che potrebbe compromettere la sicurezza.

Questo funziona anche con l'esecuzione di comandi / script che richiedono un sì per continuare:

echo $PW | yes | ./install.sh

L'eco è in risposta a un prompt, quindi puoi usare tutto ciò di cui hai bisogno, lì, se stai eseguendo altri script che richiedono richieste di progresso, in ordine sequenziale. Assicurati di sapere che, comunque, possono succedere cose brutte.


È molto più elegante e semplice, sono contento di averlo fatto scorrere fino in fondo! EDIT: aspetta, questo aggiungerà la password alla cronologia del mio terminale
Lavoro

1
Come chiedere nome utente / password con read: ryanstutorials.net/bash-scripting-tutorial/bash-input.php Questo dovrebbe evitare questo problema
Giobbe

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

0

Potresti provare ad aggiungere l'utente che esegue lo script nel file 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

Generalmente questo è un metodo scadente. Se hai intenzione di aggiungere le regole sudo NOPASSWD, in particolare per gli account che eseguono l'automazione, dovresti almeno limitarli all'esatto comando che viene eseguito (e non a TUTTI)
Christopher Hunter,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.