Bash, esegui il comando dopo aver richiamato una nuova shell


12

Sto cercando di creare una sceneggiatura come questa:

#!/bin/bash
sudo -s
something...

Quando lo eseguo, ottengo una nuova shell ma somethingviene eseguita solo quando esco dalla shell creata da sudo -s, non al suo interno.

Qualsiasi aiuto?

Risposte:


7

Il problema è che sudo -ssenza alcun argomento si aprirà una shell interattiva per root.

Se vuoi semplicemente eseguire un singolo comando utilizzando sudo -s, puoi semplicemente fare:

sudo -s command

Per esempio :

$ sudo -s whoami
root

Oppure puoi usare qui le stringhe:

$ sudo -s <<<'whoami'
root

Se hai più comandi puoi usare qui doc:

$ sudo -s <<'EOF'
> whoami
> hostname
> EOF
root
something--

1
Non è utile usarlo sudo -snel caso in cui l' rootutente abbia avuto l'idea (piuttosto scadente) di cambiare shell. Questo dovrebbe davvero essere ciò sudo shche afferma esplicitamente quale shell deve essere usata.
Michael Le Barbier Grünewald,

7

Un altro modo sarebbe quello di passare un comando bash completo a sudo:

#!/bin/bash
sudo bash -c 'command1; command2; command3;'

Tuttavia, un modo migliore sarebbe quello di avviare lo script con sudoinvece. Non è una buona idea avere sudoall'interno della sceneggiatura. Molto meglio eseguire l'intero script con i privilegi di root ( sudo script.sh). Se necessario, è possibile utilizzare sudoper eliminare i privilegi per comandi specifici. Per esempio:

#!/usr/bin/env bash
whoami
echo $HOME
sudo -u terdon whoami  ## drop privileges for specific command.

L'esecuzione dello script sopra restituisce:

$ sudo ~/scripts/a.sh
root
/root
terdon

3

La shell Bourne ha una -cbandiera che puoi usare per passare uno script arbitrario alla shell, in modo da poter scrivere qualcosa del genere

sudo sh -c 'something'

Questo è tuttavia utile solo per i comandi più semplici, perché è molto ingombrante citare correttamente lo script e l'inconveniente è ancora maggiore se si invia il comando a un server remoto su ssh perché lo script dell'argomento verrà analizzato due volte, una volta sul lato inviando lo script e una volta sul lato eseguendo lo script.

Se somethingè uno script complesso o deve essere passato su una riga ssh , è pratica comune scrivere una funzione il prepare_something_scriptcui compito è scrivere lo script "qualcosa" su stdout . Nella sua forma più semplice, questa funzione può usare un documento qui per generare il suo output:

prepare_something_script()
{
  cat <<EOF
something
EOF
}

Lo script prodotto da prepare_something_scriptpuò quindi essere eseguito localmente con i privilegi concessi da sudo come segue:

prepare_something_script | sudo sh

Nello scenario in cui lo script deve essere eseguito in remoto con i privilegi concessi da sudo è consuetudine codificare lo script in base 64 per evitare di reindirizzare l'input standard di ssh , in questo modo:

something64=$(prepare_something_script | base64)
ssh usesr@remote-host "echo ${something64} | base64 --decode | sudo sh"

Se si utilizza il codice in una funzione, non dimenticate di segnare il something64 variabile come locale . Alcune implementazioni di base64 offrono un -dflag da decodificare, che è meno ben supportato rispetto alla --decodevariante dettagliata . Alcune implementazioni richiedono di aggiungere -w 0a al comando di codifica per evitare interruzioni di riga spurie.


0

Devi aggiungere il comando prima di sudo -s, anziché nella riga successiva.

sudo -s something...
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.