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 = 'mytestaccount@gmail.com'

J'ai essayé ceci:

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

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.


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 = 'mytestaccount@gmail.com'"

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.


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'


14
J'ai trouvé cette alternative plus fiable.
Nick


42

Si vous souhaitez gérer les devis:

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

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

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;'

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

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.


1

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

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

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».


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.