允許 {USER} 針對另一個使用者擁有的進程執行命令

允許 {USER} 針對另一個使用者擁有的進程執行命令

我一直在論壇上搜索,以了解如何允許通常僅由 root 或其本身允許的用戶運行命令/進程。

那裡有一些很好的資源,但沒有一個對我的實例有幫助,我希望 Ubuntu 天才之一能為我指明正確的方向。

我已經使用 apt-get install cpulimit 安裝了 cpulimit,該軟體包增加了限制特定進程的 cpu 使用率的功能。安裝後,我可以在 /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 使用者 公關 虛擬實境技術 RES SHR S %中央處理器 %MEM 時間+ 命令
159845 mysql 20 0 1460764 608076 3772 S 15.6 29.9 862:34.15 mysqld

這讓我認為沒有必要添加允許{USER} 運行cpulimit 的初始visudo 行,但更重要的是,當{USER} 在針對有問題的進程159845 時運行cpulimit 時,這是不允許的,因為{USER}不允許沒有權限接觸 mysql 的進程。

我如何以{USER}身份在mysql的進程mysql上運行cpulimit?

GENERIC:如何在不同「使用者/帳號/角色」擁有的進程上以 {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:為什麼這不執行然後繼續執行腳本的其餘部分?

答:因為命令運行並且它開始監視該進程,防止它在我們期望返回時繼續執行程式碼,所以它將永遠掛在這裡。

Q:如何在背景觸發 cpulimit 命令的 exec(),或無需在繼續之前觀察並等待回應?

A:如果使用此函數啟動程序,為了使其繼續在背景運行,必須將程式的輸出重定向到檔案或另一個輸出流。如果不這樣做將導致 PHP 掛起,直到程式執行結束。

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

因此,本質上我們需要 > 到另一個空間,例如 /dev/null 並透過附加 & 來在後台運行該進程。就我而言,該命令需要如下所示:

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

我還切換了 exec() 來代替 shell_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 &");

相關內容