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.