{USER} erlauben, einen Befehl für einen Prozess auszuführen, der einem anderen Benutzer gehört

{USER} erlauben, einen Befehl für einen Prozess auszuführen, der einem anderen Benutzer gehört

Ich habe die Foren durchforstet, um herauszufinden, wie man einem Benutzer die Ausführung eines Befehls/Prozesses erlauben kann, zu dem normalerweise nur Root oder der Benutzer selbst berechtigt ist.

Es gibt da draußen einige gute Ressourcen, aber keine hilft mir in meinem Fall weiter. Ich hoffe, dass mir einer der Ubuntu-Genies den richtigen Weg weisen kann.

Ich habe cpulimit mit apt-get install cpulimit installiert, ein Paket, das die Möglichkeit bietet, die CPU-Auslastung durch einen bestimmten Prozess zu begrenzen. Nach der Installation kann ich die Installation in /usr/bin/cpulimit sehen.

Ich muss jetzt cpulimit ausführen, während ich einen vom Benutzer verwalteten Prozess innerhalb des Prozesscodes ausführe.

Ich habe ein paar Versuche in meine Visudo-Datei eingefügt, alle Variationen davon:

{USER} ALL=(ALL:ALL) NOPASSWD:/usr/bin/cpulimit

Wenn ich jedoch den Befehl ausführe (Limit = Prozentsatz):

cpulimit --pid 159845 --limit 60

Die Antwort lautet:

Error: Process 159845 detected, but you don't have permission to control it.

Wobei 159845 der richtige Prozess ist, es ist mysqld.

Ich kann top -i ausführen und sehen, dass der Prozess vom Benutzer mysql ausgeführt wird:

PID BENUTZER PR Deutschland VIRT RES SHR S %CPU %Speicher ZEIT+ BEFEHL
159845 MySQL 20 0 1460764 608076 3772 S 15.6 29,9 862:34.15 mysqld

Dies führt mich zu dem Schluss, dass es nicht notwendig ist, die anfängliche Visudo-Zeile hinzuzufügen, die {USER} die Ausführung von cpulimit gestattet. Vielmehr ist es nicht zulässig, wenn {USER} cpulimit ausführt, während er auf den Prozess in Frage 159845 abzielt, da {USER} keine Berechtigung hat, die Prozesse von MySQL zu berühren.

Wie kann ich als {USER} cpulimit auf dem MySQL-Prozess ausführen?

ALLGEMEIN: Wie führe ich als {USER} einen Befehl für einen Prozess aus, der einem anderen „Benutzer/Konto/einer anderen Rolle“ gehört?

BEARBEITEN: Der Befehl wird innerhalb eines Skripts ausgeführt, das innerhalb der Crontab von {USER} ausgelöst wird.

BEARBEITEN 2: Nachdem Sie den Befehl als sudo wie folgt ausgeführt haben:

$limit_mysqld_cpu_usage = "sudo -u mysql cpulimit --pid " . $mysqld_id_exe_output[0] . " --limit " . $cpu_limit_as_perc_of_cpus;

// Run command
exec($limit_mysqld_cpu_usage, $limit_mysqld_cpu_usage_output, $limit_mysqld_cpu_usage_id);

Das Skript scheint einzufrieren, obwohl es vorher mit der Ausführung des Skripts fortgefahren wäre. Es wurde getestet, dass das Skript ab diesem Punkt sehr gut funktioniert, ohne den obigen Befehl auszulösen.

F: Warum wird dies nicht ausgeführt und anschließend mit dem Rest des Skripts fortgefahren?

A: Weil der Befehl ausgeführt wird und beginnt, den Prozess zu überwachen. Er wird daran gehindert, den Code weiter auszuführen, da wir eine Rückgabe erwarten. Daher wird er hier für immer hängen bleiben.

F: Wie kann ich die exec()-Funktion des Befehls cpulimit im Hintergrund auslösen, ohne dass ich eine Antwort abwarten muss, bevor ich fortfahren kann?

A:Wenn ein Programm mit dieser Funktion gestartet wird, muss die Ausgabe des Programms in eine Datei oder einen anderen Ausgabestream umgeleitet werden, damit es im Hintergrund weiter ausgeführt werden kann. Andernfalls bleibt PHP hängen, bis die Ausführung des Programms beendet ist.

http://php.net/manual/en/function.exec.php

Im Wesentlichen müssen wir also > in einen anderen Bereich wie /dev/null wechseln und den Prozess im Hintergrund ausführen, indem wir ein & anhängen. In meinem Fall muss der Befehl folgendermaßen aussehen:

sudo -u {USER} cpulimit --pid {ID} --limit 60 > /dev/null &"

Ich habe außerdem exec() durch shell_exec() ersetzt, was anscheinend nicht alle Parameter erfordert oder eine so umfangreiche Antwort erzeugt:

shell_exec(sudo -u {USER} cpulimit --pid {ID} --limit 60 > /dev/null &");

Antwort1

Mithilfe von @steeldriver habe ich die Lösung für meine Probleme gefunden.

Um dies in chronologischer Reihenfolge zu beantworten:

Wie führe ich als {USER} einen Befehl für einen Prozess aus, der einem anderen „Benutzer/Konto/einer anderen Rolle“ gehört?

Um einen Prozess auf einem {ALTERNATIVE_USER} auszuführen, während wir als {USER} agieren, müssen wir sudo verwenden, wobei Sie dann angeben können, welcher genaue Benutzer den Befehl ausführen soll, und zwar wie folgt:

sudo -u {ALTERNATIVE_USER} {COMMAND}

Wie kann ich einen {COMMAND} auslösen, der im Hintergrund ausgeführt wird, sodass das aktuelle Skript fortgesetzt werden kann?

Das Skript scheint einzufrieren, wenn der Prozess ausgelöst wird. Es ist jedoch nicht eingefroren, sondern wartet lediglich darauf, dass der neu ausgelöste Befehl beendet wird. Dies wird jedoch nicht passieren, da es auf den ursprünglich ausgelösten Prozess einwirkt, der sein Ende nie erreichen wird.

Dazu müssen wir beim Initiieren des hängenden Befehls einen Ausgang dafür angeben, damit er irgendwo hängen kann. Dies kann durch Verweisen auf einen alternativen Ort erfolgen, in meinem Fall habe ich verwendet > /dev/null.

Zuletzt musste ich es im Hintergrund ausführen, was durch Anhängen eines möglich ist &.

Letzter Punkt: Ich wollte speziell keine Antwort erhalten, ich wollte einfach, dass der Befehl ausgeführt wird und das tut, was ich gesagt habe, also habe ich exec() durch shell_exec() ersetzt.

shell_exec(sudo -u {USER} cpulimit --pid {ID} --limit 60 /dev/null &");

verwandte Informationen