come eseguire due comandi in sudo?


152

Esiste un modo in cui posso eseguire due comandi Db2 da una riga di comando? (Saranno chiamati da un execcomando PHP .)

  1. db2 connect to ttt (nota che dobbiamo avere la connessione attiva per il secondo comando
  2. db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'

Ho provato questo:

sudo -su db2inst1 db2 connect to ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'

Il primo comando termina correttamente ma il secondo non riesce con il messaggio di errore SQL1024N A database connection does not exist. SQLSTATE=08003

Nota che devo eseguirlo come utente php. Il comando sudo -u db2inst1 idcome utente php mi dà l'output corretto.


per favore lascia un commento sul perché vuoi chiudere questa domanda. Grazie.
Radek,

1
Il voto vicino riguarda la migrazione a serverfault, poiché si tratta di una questione di amministrazione dei sistemi, non di programmazione.
bdonlan,

Risposte:


157

sudo può eseguire più comandi tramite una shell, ad esempio:

$ sudo -s - 'whoami; chi sono'
radice
radice

Il tuo comando sarebbe qualcosa del tipo:

sudo -u db2inst1 -s - "db2 connect to ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'"

Se la tua versione sudo non funziona con i punti e virgola con -s (apparentemente, se non viene compilata con determinate opzioni), puoi usare

sudo: sh -c 'whoami; chi sono'

invece, che sostanzialmente fa la stessa cosa ma ti fa nominare esplicitamente la shell.


12
questo non funziona sull'ultimo debian stable (squeeze) bash:sudo -s -- '/usr/bin/whoami; /usr/bin/whoami' /bin/bash: /usr/bin/whoami; /usr/bin/whoami: No such file or directory
Valore

11
@Valor è possibile utilizzare sudo -- sh -c 'whoami; whoami;come soluzione alternativa quando "sudo -s" è interrotto. Ho aggiornato anche la risposta.
wjl,

6
+1 per la versione modificata che mostra l'esempio "- sh -c". Grazie!
JD.

4
Puoi per favore spiegare perché hai bisogno di "-"?
Vic Seedoubleyew,

7
@VicSeedoubleyew --Indica la fine dei parametri sudo, quindi tutto il resto fa parte del comando; senza di essa, argomenti come -cpotrebbero essere interpretati come argomenti a sudo. Questo funziona per la maggior parte (ma non per tutti) i programmi da riga di comando. Per un altro (non sudo) esempio, per rimuovere un file chiamato -fnon puoi semplicemente eseguirlo rm -f, giusto ?! Ma puoi eseguire rm -- -fper eliminare il file chiamato -f.
giovedì

176

Per il tuo comando puoi anche fare riferimento al seguente esempio:

sudo sh -c 'whoami; whoami'


14
Ho trovato questa un'alternativa più affidabile.
Nick,


42

Se desideri gestire le virgolette:

sudo -s -- <<EOF
id
pwd
echo "Done."
EOF

4
Questa è la risposta più pulita qui, grazie. Forse aggiungi una nota "Non puoi eseguire più comandi da sudo- devi sempre indurlo a eseguire una shell che può accettare più comandi da eseguire come parametri"
trs

8

Un'alternativa che utilizza in evalmodo da evitare l'uso di una subshell:

sudo -s eval 'whoami; whoami'

Nota: le altre risposte usando sudo -sfalliscono perché le virgolette vengono passate a bash ed eseguite come un singolo comando, quindi è necessario rimuovere le virgolette con eval. evalè meglio spiegato è questa risposta SO

Anche la citazione all'interno dei comandi è più semplice:

$ sudo -s eval 'whoami; whoami; echo "end;"'
root
root
end;

E se i comandi devono smettere di funzionare se uno fallisce, usa la doppia e commerciale invece dei punti e virgola:

$ sudo -s eval 'whoami && whoamit && echo "end;"'
root
/bin/bash: whoamit: command not found

3

L' -sopzione non ha funzionato per me, ha -ifatto.

Ecco un esempio di come ho potuto aggiornare la dimensione del registro dalla mia bash:

sudo -u [user] -i -- sh -c 'db2 connect to [database name];db2 update db cfg for [database name] using logsecond 20;db2 update db cfg for [database name] using logprimary 20;'

1

Sul terminale, digitare:

$ sudo bash

Quindi scrivi quanti comandi vuoi. Digita exitquando hai finito.

Se è necessario automatizzarlo, creare un script.shfile ed eseguirlo:

$ sudo ./script.sh

1

Su un argomento leggermente correlato, volevo fare lo stesso sudo multi-comando tramite SSH, ma nessuno dei precedenti ha funzionato.

Ad esempio su Ubuntu,

$ ssh host.name sudo sh -c "whoami; whoami"
[sudo] password for ubuntu:
root
ubuntu

Il trucco scoperto qui è di citare due volte il comando.

$ ssh host.name sudo sh -c '"whoami; whoami"'
[sudo] password for ubuntu:
root
root

Altre opzioni che funzionano anche:

ssh host.name sudo sh -c "\"whoami; whoami\""
ssh host.name 'sudo sh -c "whoami; whoami"'

In linea di principio, sono necessarie le virgolette doppie perché penso che la shell client in cui viene eseguito SSH elimini l'insieme più esterno di virgolette. Mescola e abbina le virgolette alle tue esigenze (es. Le variabili devono essere passate). Tuttavia YMMV con le virgolette soprattutto se i comandi remoti sono complessi. In tal caso, uno strumento come Ansible farà una scelta migliore.


1

Se conosci la password di root, puoi provare

su -c "<command1> ; <command2>"  

Se non conosci la password di root, usa sudo su -c "<command1> ; <command2>" .
Dag Høidahl,

0

Le risposte sopra non ti permetteranno di citare le virgolette. Questa soluzione sarà:

sudo -su nobody umask 0000 \; mkdir -p "$targetdir"

Sia il comando umask che il comando mkdir vengono eseguiti con l'utente 'nobody'.


Puoi usare virgolette singole e doppie e sfuggirle.
Radek,

Ok, quindi come mai, ora importa cosa ho impostato l'umask in questo comando, non ha alcun effetto?
Michael,
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.