Jex’s Note

PHP - Exec() 執行系統指令

介紹

exec() 是用來執行 linux 指令的,並且可以透過它取得執行結果

分析 exec('ls -l 2>&1', $result, $is_fail)

[1] 首先第一個參數是 command line,執行的是ls -l指令

[2] 第二個參數是當執行成功才會有值,失敗則不會有值

原本執行錯誤時 $result 是不會有值的,但當 command line 加上2>&1就可以將錯誤訊息回傳給 $result

[3] 第三個參數為狀態碼,簡單來說就是執行成功為 0,非 0 則是失敗

  • 1 : Catchall for general errors
  • 2 : Misuse of shell builtins (according to Bash documentation)
  • 126 : Command invoked cannot execute
  • 127 : “command not found”
  • 128 : Invalid argument to exit

不要完全相信以上表的錯誤訊息, 建議要取得準確的錯誤訊息還是加上2>&1比較好

exec(‘sudo …..’), 使用 sudo 執行指令

[1] apache 預設執行身份在 /etc/apache2/envvars

export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data

[2] 原本是在 /etc/apache2/apache2.conf :

有些 linux 的 apache 的預設執行身份不像 ubuntu 是用變數,而是直接寫死在這的, 所以 ubuntu 的 apache2.conf 會再去 load envvars,取得 user 身份 :

User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}

[3] 執行權限設定在 /etc/sudoers , apache 預設的 http user 是 www-data

如果要用 sudoexec 執行特定指令

www-data ALL=(ALL) NOPASSWD: /usr/sbin/smartctl,/usr/bin/php

允許執行所有指令:

www-data ALL=(ALL) NOPASSWD:ALL

為了讓 exec() 執行 sudo 時不需要輸入密碼,否則 exec() 沒辦法執行

[4] 例如執行 smartctl 指令:

echo exec("sudo -u www-data sudo smartctl -i /dev/sda1");

如果 apache 預設的執行 user 是 www-data (例如: 步驟 1 預設執行 user 是 www-data),則可以省略寫成:

echo exec("sudo smartctl -i /dev/sda1");

參考來源:

Comments