sudo in script non interattivo


9

Ho uno script che esegue tre funzioni: A && B && C.

La funzione Bdeve essere eseguita come superutente, mentre Ae Cnon lo è.

Ho diverse soluzioni ma nessuna di queste è soddisfacente:

  1. sudo l'intero script: sudo 'A && B && C'

    Sembra una cattiva idea da eseguire Ae Ccome superutente se non è necessaria

  2. rendere interattivo lo script: A && sudo B && C

    Potrei dover digitare la mia password, ma voglio che il mio script non sia interattivo, poiché ogni funzione può richiedere del tempo e non voglio che lo script mi ​​aspetti. Bene, questo è anche il motivo per cui è una sceneggiatura, quindi non devo guardarla correre.

  3. La stupida soluzione: sudo : && A && sudo -n B && C

    Prima sembra stupido fare prima una no-op sudo, e anche io devo incrociare il dito che A non ne prenderà più di $sudo_timeout.

  4. Soluzione ipotetica (vorrei che tu mi dica che esiste):

    sudo --store-cred 'A && sudo --use-cred-from-parent-sudo B && C'

    Ciò richiederebbe la mia password all'inizio, e quindi userebbe tali credenziali solo quando necessario.

Qual è la tua opinione su tutto questo? Sarei molto sorpreso che non ci sia soluzione a quel problema, poiché penso che sia un problema abbastanza comune (che dire make all && sudo make install)


3
Si potrebbe fare uno script che si esegue con sudo, ma nello script eseguire il Ae Cparti utilizzando in modo esplicito su -l some_non_priviliged_user. Nessun problema di timeout e nessun privilegio per A e C. Non credo che 4 sia possibile, sudosembra uno "stato globale" per un utente.
Anthon,

Risposte:


7

Penso che la cosa migliore che puoi fare sia avviare lo script sudoe quindi avviare i processi che vuoi eseguire come un normale utente esplicitamente con su usero sudo -u user:

#!/usr/bin/env bash

## Detect the user who launched the script
usr=$(env | grep SUDO_USER | cut -d= -f 2)

## Exit if the script was not launched by root or through sudo
if [ -z $usr ] && [ $USER = "root" ]
then
    echo "The script needs to run as root" && exit 1
fi

## Run the job(s) that don't need root
sudo -u $usr commandA

## Run the job that needs to be run as root
commandB

9

Aggiungi il tuo script al /etc/sudoersfile con l' NOPASSWDattributo, in modo che sia permesso di eseguirlo senza richiedere una password. Puoi associarlo a un utente specifico (o a un insieme di utenti) o consentirne l'esecuzione con sudochiunque sul tuo sistema.

Una riga di esempio per uno script chiamato /usr/local/bin/bossypotrebbe essere simile a questa

ALL ALL = (root) NOPASSWD: /usr/local/bin/bossy

E poi useresti qualcosa del genere

A && sudo bossy && C

Per questo esempio ho assunto PATHinclude /usr/local/bin. In caso contrario, utilizza semplicemente il percorso completo dello script, ad essudo /usr/local/bin/bossy


Miglioramento per l'approccio più sicuro.
eyoung100,

0

È possibile che si desideri utilizzare l' !requirettyopzione sudoe l' NOPASSWDopzione. Ma tieni presente che questo riduce la sicurezza.


1
Poiché il problema è definito come non volere che lo script sia interattivo, # 2 con la /etc/sudoersvoce per l'utente per eseguire il comando Bcon NOPASSWDè la risposta giusta.
Andrew

Questo è "potresti fare X o Y", era "potresti fare X e Y". Solo entrambi risolveranno il problema. Forse dovrei riformulare la mia risposta.
Steve Wills,

0

Sulla base della mia risposta alla pre-autorizzazione di sudo? (Quindi può essere eseguito in un secondo momento) , scrivere due script:

  • ABC_script:

    #!/bin/sh
    sudo -b ./B_script
    A  &&  > A_is_done
    while [ ! -f B_is_done ]
    do
            sleep 60
    done
    rm -f B_is_done
    C
  • B_script:

    #!/bin/sh
    while [ ! -f A_is_done ]
    do
            sleep 60
    done
    rm -f A_is_done
    B  &&  > B_is_done

Esegui ./ABC_script:

  • Funzionerà sudo -b ./B_script. Questo richiede la password ( immediatamente dopo l'esecuzione ABC_script). Partendo dal presupposto che la password corretta viene inserita, depone le uova B_scriptin b ackground (perché -bè stato specificato) come root. Questo sembra essere equivalente a sudo sh -c "./B_script &".
  • B_scriptinizia a funzionare in modo asincrono, in parallelo con ABC_scriptB_scriptverifica l'esistenza di un file chiamato A_is_done e esegue il ciclo fino a quando non viene visualizzato.
  • In parallelo, ABC_scriptcorre A. Se / quando Atermina correttamente, lo script crea un file chiamato A_is_done.
  • ABC_scriptquindi verifica l'esistenza di un file chiamato B_is_done e esegue il ciclo fino a quando non viene visualizzato.
  • In parallelo, B_scriptrileva l'esistenza A_is_donee si interrompe dal ciclo. Elimina il A_is_donefile ed esegue B. Ricorda, B_scriptfunziona come root, quindi funziona Bcome root. Se / quando Btermina correttamente, lo script crea un file chiamato B_is_doneed esce.
  • In parallelo, ABC_scriptrileva l'esistenza B_is_donee si interrompe dal ciclo. Elimina il B_is_donefile. Ricorda, B_scripteseguito come root, quindi B_is_doneè di proprietà di root e vuoi usarlo rm -fper evitare di ottenere una richiesta di conferma. ABC_scriptquindi corre Ced esce.

Note per ulteriori perfezionamenti:

  • ABC_scriptdovrebbe probabilmente essere eseguito B_scriptda un percorso assoluto piuttosto che ./.
  • Invece di A_is_donee B_is_done, ABC_scriptprobabilmente dovrebbe generare nomi di file casuali e unici.
  • È necessario disporre di una disposizione per lo script in attesa di spin per essere avvisato se il programma che sta aspettando è terminato ma non è riuscito. (In questo momento, se Afallisce, entrambi gli script vanno semplicemente in un ciclo di attesa infinito.) Potrebbe essere semplice come cambiare

    A  &&  > A_is_done

    per

    A; echo $? > A_is_done

    e quindi modificando gli spin-wait per leggere i X_is_donefile e procedere se contiene 0 e uscire altrimenti.


-3

Sii stupido. usa molte righe.

if A; then

    if sudo B ; then
        C
    fi
fi

come risolve questa mia preoccupazione? Il problema non ha nulla a che fare con&&
Antoine Pelisse del

&& interrompe l'esecuzione quando il primo comando fallisce. Le istruzioni if ​​lo fanno in modo più dettagliato. Il mio punto è portare a termine il tuo lavoro, anche se non è carino.
Robert Jacobs,

1
Questo non è altro che una versione più dettagliata di Opzione 2: A && sudo B && C. Proprio come Antoine spiega nella domanda; questo non richiede la password fino a quando non Aè terminato, e non vuole doverlo aspettare o far aspettare lo script.
Scott,
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.