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.