
나는 일반적으로 루트나 자신에게만 허용되는 명령/프로세스를 사용자가 실행하도록 허용하는 방법을 찾기 위해 포럼을 샅샅이 뒤졌습니다.
좋은 리소스가 몇 가지 있지만 내 경우에는 아무도 나를 도와주지 않습니다. Ubuntu genii 중 하나가 나에게 올바른 방향을 알려줄 수 있기를 바랍니다.
특정 프로세스의 CPU 사용량을 제한하는 기능을 추가하는 패키지인 apt-get install cpulimit를 사용하여 cpulimit를 설치했습니다. 일단 설치되면 /usr/bin/cpulimit에서 설치를 볼 수 있습니다.
이제 해당 프로세스 코드 내에서 사용자가 처리하는 프로세스를 실행하는 동안 cpulimit를 실행해야 합니다.
내 visudo 파일에 몇 가지 시도를 추가했습니다. 모든 변형은 다음과 같습니다.
{USER} ALL=(ALL:ALL) NOPASSWD:/usr/bin/cpulimit
그러나 명령을 실행하면(한도 = 백분율):
cpulimit --pid 159845 --limit 60
응답은 다음과 같습니다.
Error: Process 159845 detected, but you don't have permission to control it.
159845가 올바른 프로세스인 경우 mysqld입니다.
top -i를 실행하면 mysql 사용자가 프로세스를 실행하는 것을 확인할 수 있습니다.
PID | 사용자 | 홍보 | NI | 버트 | RES | SHR | 에스 | %CPU | %MEM | 시간+ | 명령 |
---|---|---|---|---|---|---|---|---|---|---|---|
159845 | mysql | 20 | 0 | 1460764 | 608076 | 3772 | 에스 | 15.6 | 29.9 | 862:34.15 | mysqld |
이로 인해 {USER}가 cpulimit를 실행하도록 허용하는 초기 visudo 줄을 추가할 필요가 없다고 생각하게 되지만, {USER}가 문제 159845의 프로세스를 대상으로 하는 동안 cpulimit를 실행할 때 {USER}가 허용되지 않으므로 더 그렇습니다. mysql의 프로세스를 건드릴 수 있는 권한이 없습니다.
{USER}로서 mysql의 프로세스 mysql에서 cpulimit를 어떻게 실행할 수 있나요?
일반: 다른 '사용자/계정/역할'이 소유한 프로세스에서 {USER}로 명령을 실행하는 방법은 무엇입니까?
편집하다: 명령이 {USER}의 crontab 내에서 트리거된 스크립트 내에서 실행되고 있습니다.
편집 2: 다음과 같이 sudo로 명령을 실행한 후:
$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);
이전에는 스크립트를 계속 진행하던 스크립트가 정지된 것 같습니다. 이 지점 이후의 스크립트는 위 명령을 실행하지 않고도 매우 잘 작동하도록 시도되고 테스트되었습니다.
Q: 이것이 실행되지 않고 나머지 스크립트를 계속 진행하는 이유는 무엇입니까?
A: 명령이 실행되고 해당 프로세스를 감시하기 시작하기 때문에 반환을 기대하는 동안 코드를 통해 프로세스가 진행되지 않으므로 여기서 영원히 정지됩니다.
Q: 백그라운드에서 또는 계속하기 전에 응답을 관찰하고 기다릴 필요 없이 CPUlimit 명령의 exec()를 어떻게 트리거할 수 있습니까?
ㅏ:이 기능을 사용하여 프로그램을 시작한 경우 프로그램이 백그라운드에서 계속 실행되도록 하려면 프로그램의 출력을 파일이나 다른 출력 스트림으로 리디렉션해야 합니다. 그렇게 하지 않으면 프로그램 실행이 끝날 때까지 PHP가 정지됩니다.
http://php.net/manual/en/function.exec.php
따라서 기본적으로 /dev/null과 같은 다른 공간으로 이동하고 &를 추가하여 백그라운드에서 프로세스를 실행해야 합니다. 제 경우에는 명령이 다음과 같아야 합니다.
sudo -u {USER} cpulimit --pid {ID} --limit 60 > /dev/null &"
또한 모든 매개변수가 필요하지 않거나 응답이 너무 많이 생성되는 shell_exec() 대신 exec()를 사용하지 않도록 설정했습니다.
shell_exec(sudo -u {USER} cpulimit --pid {ID} --limit 60 > /dev/null &");
답변1
@steeldriver의 도움으로 문제에 대한 해결책을 찾았습니다.
시간순으로 대답하려면 다음을 수행하십시오.
다른 '사용자/계정/역할'이 소유한 프로세스에서 {USER}로 명령을 실행하는 방법은 무엇입니까?
{USER} 역할을 하는 동안 {ALTERNATIVE_USER}에서 프로세스를 실행하려면 sudo를 사용해야 합니다. 그러면 다음과 같이 명령을 실행해야 하는 정확한 사용자를 지정할 수 있습니다.
sudo -u {ALTERNATIVE_USER} {COMMAND}
현재 스크립트가 계속되도록 {COMMAND}를 백그라운드에서 실행하도록 트리거하려면 어떻게 해야 합니까?
스크립트는 프로세스가 트리거될 때 정지되는 것처럼 보이지만 정지되지는 않습니다. 단순히 새로 트리거된 명령이 끝나기를 기다리고 있는 것입니다. 처음에 트리거된 프로세스에서 작동하므로 결코 끝나지 않을 것입니다.
중단된 명령을 시작할 때 이를 수행하려면 중단될 위치가 있도록 해당 명령에 대한 콘센트를 지정해야 합니다. 대체 위치를 지정하면 이 작업을 수행할 수 있습니다. 제 경우에는 > /dev/null
.
마지막으로 제가 해야 할 일은 백그라운드에서 실행하는 것이었습니다. 이 작업은 &
.
마지막 요점은 특히 응답을 받고 싶지 않았기 때문에 명령이 실행되어 내가 말한 대로 수행되기를 원했기 때문에 exec()를 shell_exec()로 교체했습니다.
shell_exec(sudo -u {USER} cpulimit --pid {ID} --limit 60 /dev/null &");