Wie führe ich zwei Befehle in Sudo aus?

152

Gibt es eine Möglichkeit, wie ich zwei Db2-Befehle über eine Befehlszeile ausführen kann? (Sie werden von einem PHP- execBefehl aufgerufen .)

  1. db2 connect to ttt (Beachten Sie, dass die Verbindung für den zweiten Befehl aktiv sein muss
  2. db2 UPDATE CONTACT SET EMAIL_ADDRESS = '[email protected]'

Ich habe es versucht:

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

Der erste Befehl wird korrekt beendet, der zweite schlägt jedoch mit der Fehlermeldung fehl SQL1024N A database connection does not exist. SQLSTATE=08003

Beachten Sie, dass ich dies als PHP-Benutzer ausführen muss. Der Befehl sudo -u db2inst1 idals PHP- Benutzer gibt mir die richtige Ausgabe.

Radek
quelle
Bitte hinterlassen Sie einen Kommentar, warum Sie diese Frage schließen möchten. Danke dir.
Radek
1
Die enge Abstimmung ist für die Migration auf Serverfehler, da dies eine Frage der Systemadministration ist, nicht die Programmierung.
Bdonlan

Antworten:

157

sudo kann mehrere Befehle über eine Shell ausführen, zum Beispiel:

$ sudo -s - 'whoami; Wer bin ich'
Wurzel
Wurzel

Ihr Befehl wäre so etwas wie:

sudo -u db2inst1 -s - "db2 verbinde dich mit ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = '[email protected]'"

Wenn Ihre Sudo-Version nicht mit Semikolons mit -s funktioniert (anscheinend nicht, wenn sie mit bestimmten Optionen kompiliert wurde), können Sie sie verwenden

sudo - sh-c 'whoami; Wer bin ich'

Stattdessen wird im Grunde das Gleiche getan, aber Sie müssen die Shell explizit benennen.

wjl
quelle
12
Dies funktioniert nicht auf der neuesten 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 können Sie sudo -- sh -c 'whoami; whoami;als Problemumgehung verwenden, wenn "sudo -s" fehlerhaft ist. Ich habe die Antwort ebenfalls aktualisiert.
wjl
6
+1 für die bearbeitete Version, die das Beispiel "- sh -c" zeigt. Vielen Dank!
JD.
4
Können Sie bitte erklären, warum Sie "-" brauchen?
Vic Seedoubleyew
7
@VicSeedoubleyew Das --gibt das Ende der Parameter an sudo, sodass alles andere Teil des Befehls ist. ohne sie -ckönnten Argumente wie als Argument für interpretiert werden sudo. Dies funktioniert für die meisten (aber nicht alle) Befehlszeilenprogramme. Für ein anderes (Nicht- sudo) Beispiel, um eine Datei namens zu entfernen -f, können Sie nicht einfach ausführen rm -f, oder?! Sie können jedoch ausführen rm -- -f, um die aufgerufene Datei zu löschen -f.
wjl
176

Für Ihren Befehl können Sie sich auch auf das folgende Beispiel beziehen:

sudo sh -c 'whoami; whoami'

Jason
quelle
14
Ich habe festgestellt, dass dies eine zuverlässigere Alternative ist.
Nick
44

Normalerweise mache ich:

sudo bash -c 'whoami; whoami'
Samer Atiani
quelle
42

Wenn Sie Angebote bearbeiten möchten:

sudo -s -- <<EOF
id
pwd
echo "Done."
EOF
Nebojša
quelle
4
Dies ist die sauberste Antwort hier, danke. Fügen Sie möglicherweise einen Hinweis hinzu: "Sie können nicht mehrere Befehle ausführen sudo- Sie müssen ihn immer dazu
verleiten
8

Eine Alternative, bei der evaldie Verwendung einer Unterschale vermieden wird:

sudo -s eval 'whoami; whoami'

Hinweis: Die anderen Antworten mit " sudo -sfehlschlagen", da die Anführungszeichen an bash weitergeleitet und als einzelner Befehl ausgeführt werden. Daher müssen Anführungszeichen mit "eval" entfernt werden. evalBesser erklärt ist diese SO Antwort

Das Zitieren innerhalb der Befehle ist ebenfalls einfacher:

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

Und wenn die Befehle nicht mehr ausgeführt werden müssen, wenn einer fehlschlägt, verwenden Sie Doppel-Et-Zeichen anstelle von Semikolons:

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

Die -sOption hat bei mir nicht funktioniert -i.

Hier ist ein Beispiel, wie ich die Protokollgröße aus meiner Bash aktualisieren kann:

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
quelle
1

Geben Sie auf dem Terminal Folgendes ein:

$ sudo bash

Schreiben Sie dann so viele Befehle, wie Sie möchten. Geben exitSie ein, wenn Sie fertig sind.

Wenn Sie es automatisieren müssen, erstellen Sie eine script.shDatei und führen Sie sie aus:

$ sudo ./script.sh
Moshe Simantov
quelle
1

Bei einem etwas verwandten Thema wollte ich das gleiche Multi-Command-Sudo über SSH ausführen, aber keines der oben genannten Verfahren hat funktioniert.

Zum Beispiel unter Ubuntu,

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

Der hier entdeckte Trick besteht darin, den Befehl in doppelte Anführungszeichen zu setzen.

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

Andere Optionen, die auch funktionieren:

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

Im Prinzip sind doppelte Anführungszeichen erforderlich, da ich denke, dass die Client-Shell, in der SSH ausgeführt wird, die äußersten Anführungszeichen entfernt. Mischen Sie die Anführungszeichen und passen Sie sie an Ihre Bedürfnisse an (z. B. müssen Variablen übergeben werden). Allerdings YMMV mit den Anführungszeichen, insbesondere wenn die Remote-Befehle komplex sind. In diesem Fall trifft ein Tool wie Ansible eine bessere Wahl.

Eugene Chow
quelle
1

Wenn Sie das Root-Passwort kennen, können Sie es versuchen

su -c "<command1> ; <command2>"  
Scherben
quelle
Wenn Sie das Root-Passwort nicht kennen, verwenden Sie sudo su -c "<command1> ; <command2>" .
Dag Høidahl
0

Mit den obigen Antworten können Sie nicht innerhalb der Anführungszeichen zitieren. Diese Lösung wird:

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

Sowohl der Befehl umask als auch der Befehl mkdir werden mit dem Benutzer 'Nobody' ausgeführt.

Arberg
quelle
Sie können einfache und doppelte Anführungszeichen verwenden und diese maskieren.
Radek
Ok, wie kommt es, dass es keine Auswirkung hat, egal auf was ich die Umask in diesem Befehl eingestellt habe?
Michael