comment exécuter deux commandes dans sudo?

152

Existe-t-il un moyen d'exécuter deux commandes Db2 à partir d'une ligne de commande? (Ils seront appelés à partir d'une execcommande PHP .)

  1. db2 connect to ttt (notez que nous devons avoir la connexion en direct pour la deuxième commande
  2. db2 UPDATE CONTACT SET EMAIL_ADDRESS = '[email protected]'

J'ai essayé ceci:

sudo -su db2inst1 db2 connect to ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = '[email protected]'

La première commande se termine correctement mais la seconde échoue avec le message d'erreur SQL1024N A database connection does not exist. SQLSTATE=08003

Notez que je dois l'exécuter en tant qu'utilisateur php. La commande en sudo -u db2inst1 idtant qu'utilisateur php me donne une sortie correcte.

Radek
la source
s'il vous plaît laissez un commentaire pourquoi vous souhaitez fermer cette question. Je vous remercie.
Radek
1
Le vote serré est pour la migration vers serverfault, car il s'agit d'une question d'administration système, pas de programmation.
bdonlan

Réponses:

157

sudo peut exécuter plusieurs commandes via un shell, par exemple:

$ sudo -s - 'whoami; qui suis je'
racine
racine

Votre commande serait quelque chose comme:

sudo -u db2inst1 -s - "db2 connect to ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = '[email protected]'"

Si votre version sudo ne fonctionne pas avec des points-virgules avec -s (apparemment, ce n'est pas le cas si compilé avec certaines options), vous pouvez utiliser

sudo - sh -c 'whoami; qui suis je'

à la place, qui fait essentiellement la même chose mais vous oblige à nommer le shell explicitement.

wjl
la source
12
cela ne fonctionne pas sur le dernier 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
Valor
11
@Valor vous pouvez utiliser sudo -- sh -c 'whoami; whoami;comme solution de contournement lorsque "sudo -s" est cassé. J'ai également mis à jour la réponse.
wjl
6
+1 pour la version modifiée qui montre l'exemple "- sh -c". Merci!
JD.
4
Pouvez-vous expliquer pourquoi vous avez besoin de "-"?
Vic Seedoubleyew
7
@VicSeedoubleyew Le --indique la fin des paramètres à sudo, donc tout le reste fait partie de la commande; sans elle, des arguments comme -cpourraient être interprétés comme un argument de sudo. Cela fonctionne pour la plupart des programmes de ligne de commande (mais pas tous). Pour un autre (non- sudo) exemple, pour supprimer un fichier appelé, -fvous ne pouvez pas simplement exécuter rm -f, non ?! Mais vous pouvez exécuter rm -- -fpour supprimer le fichier appelé -f.
wjl
176

Pour votre commande, vous pouvez également vous référer à l'exemple suivant:

sudo sh -c 'whoami; whoami'

Jason
la source
14
J'ai trouvé cette alternative plus fiable.
Nick
44

Je fais habituellement:

sudo bash -c 'whoami; whoami'
Samer Atiani
la source
42

Si vous souhaitez gérer les devis:

sudo -s -- <<EOF
id
pwd
echo "Done."
EOF
Nebojša
la source
4
C'est la réponse la plus claire ici, merci. Peut-être ajouter une note "Vous ne pouvez pas exécuter plusieurs commandes à partir de sudo- vous devez toujours le tromper en exécutant un shell qui peut accepter plusieurs commandes à exécuter en tant que paramètres"
très
8

Une alternative utilisant evalafin d'éviter l'utilisation d'un sous-shell:

sudo -s eval 'whoami; whoami'

Remarque: les autres réponses utilisant sudo -séchouent car les guillemets sont transmis à bash et exécutés en une seule commande, il faut donc supprimer les guillemets avec eval. evalest mieux expliqué est cette réponse SO

Citer dans les commandes est également plus facile:

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

Et si les commandes doivent s'arrêter si l'une d'elles échoue, utilisez des doubles-esperluettes au lieu de points-virgules:

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

L' -soption n'a pas fonctionné pour moi -i.

Voici un exemple de la façon dont je pourrais mettre à jour la taille du journal à partir de mon 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;'
user2597485
la source
1

Sur le terminal, tapez:

$ sudo bash

Ensuite, écrivez autant de commandes que vous le souhaitez. Tapez exitquand vous avez terminé.

Si vous avez besoin de l'automatiser, créez un script.shfichier et exécutez-le:

$ sudo ./script.sh
Moshe Simantov
la source
1

Sur un sujet légèrement lié, je voulais faire le même sudo multi-commandes via SSH mais rien de ce qui précède n'a fonctionné.

Par exemple sur Ubuntu,

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

L'astuce découverte ici est de doubler la commande.

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

Autres options qui fonctionnent également:

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

En principe, des guillemets doubles sont nécessaires car je pense que le shell client sur lequel SSH est exécuté supprime l'ensemble de guillemets le plus extérieur. Mélangez et associez les citations à vos besoins (par exemple, les variables doivent être transmises). Cependant YMMV avec les guillemets surtout si les commandes à distance sont complexes. Dans ce cas, un outil comme Ansible fera un meilleur choix.

Eugène Chow
la source
1

Si vous connaissez le mot de passe root, vous pouvez essayer

su -c "<command1> ; <command2>"  
fragments
la source
Si vous ne connaissez pas le mot de passe root, utilisez sudo su -c "<command1> ; <command2>" .
Dag Høidahl le
0

Les réponses ci-dessus ne vous permettront pas de citer à l'intérieur des guillemets. Cette solution va:

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

La commande umask et la commande mkdir s'exécutent toutes deux avec l'utilisateur «personne».

Arberg
la source
Vous pouvez utiliser des guillemets simples et doubles et les échapper.
Radek le
Ok, alors comment se fait-il, maintenant que j'ai défini le umask dans cette commande, cela n'a aucun effet?
Michael